| Index: third_party/libpng/contrib/visupng/cexcept.h
|
| diff --git a/third_party/libpng/contrib/visupng/cexcept.h b/third_party/libpng/contrib/visupng/cexcept.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..5f45d76975811eddd1260b7b60292d5c30f27f2e
|
| --- /dev/null
|
| +++ b/third_party/libpng/contrib/visupng/cexcept.h
|
| @@ -0,0 +1,248 @@
|
| +/*===
|
| +cexcept.h 2.0.1 (2008-Jul-19-Sat)
|
| +http://www.nicemice.net/cexcept/
|
| +Adam M. Costello
|
| +http://www.nicemice.net/amc/
|
| +
|
| +An interface for exception-handling in ANSI C (C89 and subsequent ISO
|
| +standards), developed jointly with Cosmin Truta.
|
| +
|
| + Copyright (c) 2000-2008 Adam M. Costello and Cosmin Truta.
|
| + This software may be modified only if its author and version
|
| + information is updated accurately, and may be redistributed
|
| + only if accompanied by this unaltered notice. Subject to those
|
| + restrictions, permission is granted to anyone to do anything
|
| + with this software. The copyright holders make no guarantees
|
| + regarding this software, and are not responsible for any damage
|
| + resulting from its use.
|
| +
|
| +The cexcept interface is not compatible with and cannot interact
|
| +with system exceptions (like division by zero or memory segmentation
|
| +violation), compiler-generated exceptions (like C++ exceptions), or
|
| +other exception-handling interfaces.
|
| +
|
| +When using this interface across multiple .c files, do not include
|
| +this header file directly. Instead, create a wrapper header file that
|
| +includes this header file and then invokes the define_exception_type
|
| +macro (see below). The .c files should then include that header file.
|
| +
|
| +The interface consists of one type, one well-known name, and six macros.
|
| +
|
| +
|
| +define_exception_type(type_name);
|
| +
|
| + This macro is used like an external declaration. It specifies
|
| + the type of object that gets copied from the exception thrower to
|
| + the exception catcher. The type_name can be any type that can be
|
| + assigned to, that is, a non-constant arithmetic type, struct, union,
|
| + or pointer. Examples:
|
| +
|
| + define_exception_type(int);
|
| +
|
| + enum exception { out_of_memory, bad_arguments, disk_full };
|
| + define_exception_type(enum exception);
|
| +
|
| + struct exception { int code; const char *msg; };
|
| + define_exception_type(struct exception);
|
| +
|
| + Because throwing an exception causes the object to be copied (not
|
| + just once, but twice), programmers may wish to consider size when
|
| + choosing the exception type.
|
| +
|
| +
|
| +struct exception_context;
|
| +
|
| + This type may be used after the define_exception_type() macro has
|
| + been invoked. A struct exception_context must be known to both
|
| + the thrower and the catcher. It is expected that there be one
|
| + context for each thread that uses exceptions. It would certainly
|
| + be dangerous for multiple threads to access the same context.
|
| + One thread can use multiple contexts, but that is likely to be
|
| + confusing and not typically useful. The application can allocate
|
| + this structure in any way it pleases--automatic, static, or dynamic.
|
| + The application programmer should pretend not to know the structure
|
| + members, which are subject to change.
|
| +
|
| +
|
| +struct exception_context *the_exception_context;
|
| +
|
| + The Try/Catch and Throw statements (described below) implicitly
|
| + refer to a context, using the name the_exception_context. It is
|
| + the application's responsibility to make sure that this name yields
|
| + the address of a mutable (non-constant) struct exception_context
|
| + wherever those statements are used. Subject to that constraint, the
|
| + application may declare a variable of this name anywhere it likes
|
| + (inside a function, in a parameter list, or externally), and may
|
| + use whatever storage class specifiers (static, extern, etc) or type
|
| + qualifiers (const, volatile, etc) it likes. Examples:
|
| +
|
| + static struct exception_context
|
| + * const the_exception_context = &foo;
|
| +
|
| + { struct exception_context *the_exception_context = bar; ... }
|
| +
|
| + int blah(struct exception_context *the_exception_context, ...);
|
| +
|
| + extern struct exception_context the_exception_context[1];
|
| +
|
| + The last example illustrates a trick that avoids creating a pointer
|
| + object separate from the structure object.
|
| +
|
| + The name could even be a macro, for example:
|
| +
|
| + struct exception_context ec_array[numthreads];
|
| + #define the_exception_context (ec_array + thread_id)
|
| +
|
| + Be aware that the_exception_context is used several times by the
|
| + Try/Catch/Throw macros, so it shouldn't be expensive or have side
|
| + effects. The expansion must be a drop-in replacement for an
|
| + identifier, so it's safest to put parentheses around it.
|
| +
|
| +
|
| +void init_exception_context(struct exception_context *ec);
|
| +
|
| + For context structures allocated statically (by an external
|
| + definition or using the "static" keyword), the implicit
|
| + initialization to all zeros is sufficient, but contexts allocated
|
| + by other means must be initialized using this macro before they
|
| + are used by a Try/Catch statement. It does no harm to initialize
|
| + a context more than once (by using this macro on a statically
|
| + allocated context, or using this macro twice on the same context),
|
| + but a context must not be re-initialized after it has been used by a
|
| + Try/Catch statement.
|
| +
|
| +
|
| +Try statement
|
| +Catch (expression) statement
|
| +
|
| + The Try/Catch/Throw macros are capitalized in order to avoid
|
| + confusion with the C++ keywords, which have subtly different
|
| + semantics.
|
| +
|
| + A Try/Catch statement has a syntax similar to an if/else statement,
|
| + except that the parenthesized expression goes after the second
|
| + keyword rather than the first. As with if/else, there are two
|
| + clauses, each of which may be a simple statement ending with a
|
| + semicolon or a brace-enclosed compound statement. But whereas
|
| + the else clause is optional, the Catch clause is required. The
|
| + expression must be a modifiable lvalue (something capable of being
|
| + assigned to) of the same type (disregarding type qualifiers) that
|
| + was passed to define_exception_type().
|
| +
|
| + If a Throw that uses the same exception context as the Try/Catch is
|
| + executed within the Try clause (typically within a function called
|
| + by the Try clause), and the exception is not caught by a nested
|
| + Try/Catch statement, then a copy of the exception will be assigned
|
| + to the expression, and control will jump to the Catch clause. If no
|
| + such Throw is executed, then the assignment is not performed, and
|
| + the Catch clause is not executed.
|
| +
|
| + The expression is not evaluated unless and until the exception is
|
| + caught, which is significant if it has side effects, for example:
|
| +
|
| + Try foo();
|
| + Catch (p[++i].e) { ... }
|
| +
|
| + IMPORTANT: Jumping into or out of a Try clause (for example via
|
| + return, break, continue, goto, longjmp) is forbidden--the compiler
|
| + will not complain, but bad things will happen at run-time. Jumping
|
| + into or out of a Catch clause is okay, and so is jumping around
|
| + inside a Try clause. In many cases where one is tempted to return
|
| + from a Try clause, it will suffice to use Throw, and then return
|
| + from the Catch clause. Another option is to set a flag variable and
|
| + use goto to jump to the end of the Try clause, then check the flag
|
| + after the Try/Catch statement.
|
| +
|
| + IMPORTANT: The values of any non-volatile automatic variables
|
| + changed within the Try clause are undefined after an exception is
|
| + caught. Therefore, variables modified inside the Try block whose
|
| + values are needed later outside the Try block must either use static
|
| + storage or be declared with the "volatile" type qualifier.
|
| +
|
| +
|
| +Throw expression;
|
| +
|
| + A Throw statement is very much like a return statement, except that
|
| + the expression is required. Whereas return jumps back to the place
|
| + where the current function was called, Throw jumps back to the Catch
|
| + clause of the innermost enclosing Try clause. The expression must
|
| + be compatible with the type passed to define_exception_type(). The
|
| + exception must be caught, otherwise the program may crash.
|
| +
|
| + Slight limitation: If the expression is a comma-expression, it must
|
| + be enclosed in parentheses.
|
| +
|
| +
|
| +Try statement
|
| +Catch_anonymous statement
|
| +
|
| + When the value of the exception is not needed, a Try/Catch statement
|
| + can use Catch_anonymous instead of Catch (expression).
|
| +
|
| +
|
| +Everything below this point is for the benefit of the compiler. The
|
| +application programmer should pretend not to know any of it, because it
|
| +is subject to change.
|
| +
|
| +===*/
|
| +
|
| +
|
| +#ifndef CEXCEPT_H
|
| +#define CEXCEPT_H
|
| +
|
| +
|
| +#include <setjmp.h>
|
| +
|
| +#define define_exception_type(etype) \
|
| +struct exception_context { \
|
| + jmp_buf *penv; \
|
| + int caught; \
|
| + volatile struct { etype etmp; } v; \
|
| +}
|
| +
|
| +/* etmp must be volatile because the application might use automatic */
|
| +/* storage for the_exception_context, and etmp is modified between */
|
| +/* the calls to setjmp() and longjmp(). A wrapper struct is used to */
|
| +/* avoid warnings about a duplicate volatile qualifier in case etype */
|
| +/* already includes it. */
|
| +
|
| +#define init_exception_context(ec) ((void)((ec)->penv = 0))
|
| +
|
| +#define Try \
|
| + { \
|
| + jmp_buf *exception__prev, exception__env; \
|
| + exception__prev = the_exception_context->penv; \
|
| + the_exception_context->penv = &exception__env; \
|
| + if (setjmp(exception__env) == 0) { \
|
| + do
|
| +
|
| +#define exception__catch(action) \
|
| + while (the_exception_context->caught = 0, \
|
| + the_exception_context->caught); \
|
| + } \
|
| + else { \
|
| + the_exception_context->caught = 1; \
|
| + } \
|
| + the_exception_context->penv = exception__prev; \
|
| + } \
|
| + if (!the_exception_context->caught || action) { } \
|
| + else
|
| +
|
| +#define Catch(e) exception__catch(((e) = the_exception_context->v.etmp, 0))
|
| +#define Catch_anonymous exception__catch(0)
|
| +
|
| +/* Try ends with do, and Catch begins with while(0) and ends with */
|
| +/* else, to ensure that Try/Catch syntax is similar to if/else */
|
| +/* syntax. */
|
| +/* */
|
| +/* The 0 in while(0) is expressed as x=0,x in order to appease */
|
| +/* compilers that warn about constant expressions inside while(). */
|
| +/* Most compilers should still recognize that the condition is always */
|
| +/* false and avoid generating code for it. */
|
| +
|
| +#define Throw \
|
| + for (;; longjmp(*the_exception_context->penv, 1)) \
|
| + the_exception_context->v.etmp =
|
| +
|
| +
|
| +#endif /* CEXCEPT_H */
|
|
|