diff options
Diffstat (limited to 'libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/cexcept.h')
-rw-r--r-- | libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/cexcept.h | 248 |
1 files changed, 248 insertions, 0 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/cexcept.h b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/cexcept.h new file mode 100644 index 0000000..83c8bfe --- /dev/null +++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/visupng/cexcept.h | |||
@@ -0,0 +1,248 @@ | |||
1 | /*=== | ||
2 | cexcept.h 2.0.1 (2008-Jul-19-Sat) | ||
3 | http://www.nicemice.net/cexcept/ | ||
4 | Adam M. Costello | ||
5 | http://www.nicemice.net/amc/ | ||
6 | |||
7 | An interface for exception-handling in ANSI C (C89 and subsequent ISO | ||
8 | standards), developed jointly with Cosmin Truta. | ||
9 | |||
10 | Copyright (c) 2000-2008 Adam M. Costello and Cosmin Truta. | ||
11 | This software may be modified only if its author and version | ||
12 | information is updated accurately, and may be redistributed | ||
13 | only if accompanied by this unaltered notice. Subject to those | ||
14 | restrictions, permission is granted to anyone to do anything | ||
15 | with this software. The copyright holders make no guarantees | ||
16 | regarding this software, and are not responsible for any damage | ||
17 | resulting from its use. | ||
18 | |||
19 | The cexcept interface is not compatible with and cannot interact | ||
20 | with system exceptions (like division by zero or memory segmentation | ||
21 | violation), compiler-generated exceptions (like C++ exceptions), or | ||
22 | other exception-handling interfaces. | ||
23 | |||
24 | When using this interface across multiple .c files, do not include | ||
25 | this header file directly. Instead, create a wrapper header file that | ||
26 | includes this header file and then invokes the define_exception_type | ||
27 | macro (see below). The .c files should then include that header file. | ||
28 | |||
29 | The interface consists of one type, one well-known name, and six macros. | ||
30 | |||
31 | |||
32 | define_exception_type(type_name); | ||
33 | |||
34 | This macro is used like an external declaration. It specifies | ||
35 | the type of object that gets copied from the exception thrower to | ||
36 | the exception catcher. The type_name can be any type that can be | ||
37 | assigned to, that is, a non-constant arithmetic type, struct, union, | ||
38 | or pointer. Examples: | ||
39 | |||
40 | define_exception_type(int); | ||
41 | |||
42 | enum exception { out_of_memory, bad_arguments, disk_full }; | ||
43 | define_exception_type(enum exception); | ||
44 | |||
45 | struct exception { int code; const char *msg; }; | ||
46 | define_exception_type(struct exception); | ||
47 | |||
48 | Because throwing an exception causes the object to be copied (not | ||
49 | just once, but twice), programmers may wish to consider size when | ||
50 | choosing the exception type. | ||
51 | |||
52 | |||
53 | struct exception_context; | ||
54 | |||
55 | This type may be used after the define_exception_type() macro has | ||
56 | been invoked. A struct exception_context must be known to both | ||
57 | the thrower and the catcher. It is expected that there be one | ||
58 | context for each thread that uses exceptions. It would certainly | ||
59 | be dangerous for multiple threads to access the same context. | ||
60 | One thread can use multiple contexts, but that is likely to be | ||
61 | confusing and not typically useful. The application can allocate | ||
62 | this structure in any way it pleases--automatic, static, or dynamic. | ||
63 | The application programmer should pretend not to know the structure | ||
64 | members, which are subject to change. | ||
65 | |||
66 | |||
67 | struct exception_context *the_exception_context; | ||
68 | |||
69 | The Try/Catch and Throw statements (described below) implicitly | ||
70 | refer to a context, using the name the_exception_context. It is | ||
71 | the application's responsibility to make sure that this name yields | ||
72 | the address of a mutable (non-constant) struct exception_context | ||
73 | wherever those statements are used. Subject to that constraint, the | ||
74 | application may declare a variable of this name anywhere it likes | ||
75 | (inside a function, in a parameter list, or externally), and may | ||
76 | use whatever storage class specifiers (static, extern, etc) or type | ||
77 | qualifiers (const, volatile, etc) it likes. Examples: | ||
78 | |||
79 | static struct exception_context | ||
80 | * const the_exception_context = &foo; | ||
81 | |||
82 | { struct exception_context *the_exception_context = bar; ... } | ||
83 | |||
84 | int blah(struct exception_context *the_exception_context, ...); | ||
85 | |||
86 | extern struct exception_context the_exception_context[1]; | ||
87 | |||
88 | The last example illustrates a trick that avoids creating a pointer | ||
89 | object separate from the structure object. | ||
90 | |||
91 | The name could even be a macro, for example: | ||
92 | |||
93 | struct exception_context ec_array[numthreads]; | ||
94 | #define the_exception_context (ec_array + thread_id) | ||
95 | |||
96 | Be aware that the_exception_context is used several times by the | ||
97 | Try/Catch/Throw macros, so it shouldn't be expensive or have side | ||
98 | effects. The expansion must be a drop-in replacement for an | ||
99 | identifier, so it's safest to put parentheses around it. | ||
100 | |||
101 | |||
102 | void init_exception_context(struct exception_context *ec); | ||
103 | |||
104 | For context structures allocated statically (by an external | ||
105 | definition or using the "static" keyword), the implicit | ||
106 | initialization to all zeros is sufficient, but contexts allocated | ||
107 | by other means must be initialized using this macro before they | ||
108 | are used by a Try/Catch statement. It does no harm to initialize | ||
109 | a context more than once (by using this macro on a statically | ||
110 | allocated context, or using this macro twice on the same context), | ||
111 | but a context must not be re-initialized after it has been used by a | ||
112 | Try/Catch statement. | ||
113 | |||
114 | |||
115 | Try statement | ||
116 | Catch (expression) statement | ||
117 | |||
118 | The Try/Catch/Throw macros are capitalized in order to avoid | ||
119 | confusion with the C++ keywords, which have subtly different | ||
120 | semantics. | ||
121 | |||
122 | A Try/Catch statement has a syntax similar to an if/else statement, | ||
123 | except that the parenthesized expression goes after the second | ||
124 | keyword rather than the first. As with if/else, there are two | ||
125 | clauses, each of which may be a simple statement ending with a | ||
126 | semicolon or a brace-enclosed compound statement. But whereas | ||
127 | the else clause is optional, the Catch clause is required. The | ||
128 | expression must be a modifiable lvalue (something capable of being | ||
129 | assigned to) of the same type (disregarding type qualifiers) that | ||
130 | was passed to define_exception_type(). | ||
131 | |||
132 | If a Throw that uses the same exception context as the Try/Catch is | ||
133 | executed within the Try clause (typically within a function called | ||
134 | by the Try clause), and the exception is not caught by a nested | ||
135 | Try/Catch statement, then a copy of the exception will be assigned | ||
136 | to the expression, and control will jump to the Catch clause. If no | ||
137 | such Throw is executed, then the assignment is not performed, and | ||
138 | the Catch clause is not executed. | ||
139 | |||
140 | The expression is not evaluated unless and until the exception is | ||
141 | caught, which is significant if it has side effects, for example: | ||
142 | |||
143 | Try foo(); | ||
144 | Catch (p[++i].e) { ... } | ||
145 | |||
146 | IMPORTANT: Jumping into or out of a Try clause (for example via | ||
147 | return, break, continue, goto, longjmp) is forbidden--the compiler | ||
148 | will not complain, but bad things will happen at run-time. Jumping | ||
149 | into or out of a Catch clause is okay, and so is jumping around | ||
150 | inside a Try clause. In many cases where one is tempted to return | ||
151 | from a Try clause, it will suffice to use Throw, and then return | ||
152 | from the Catch clause. Another option is to set a flag variable and | ||
153 | use goto to jump to the end of the Try clause, then check the flag | ||
154 | after the Try/Catch statement. | ||
155 | |||
156 | IMPORTANT: The values of any non-volatile automatic variables | ||
157 | changed within the Try clause are undefined after an exception is | ||
158 | caught. Therefore, variables modified inside the Try block whose | ||
159 | values are needed later outside the Try block must either use static | ||
160 | storage or be declared with the "volatile" type qualifier. | ||
161 | |||
162 | |||
163 | Throw expression; | ||
164 | |||
165 | A Throw statement is very much like a return statement, except that | ||
166 | the expression is required. Whereas return jumps back to the place | ||
167 | where the current function was called, Throw jumps back to the Catch | ||
168 | clause of the innermost enclosing Try clause. The expression must | ||
169 | be compatible with the type passed to define_exception_type(). The | ||
170 | exception must be caught, otherwise the program may crash. | ||
171 | |||
172 | Slight limitation: If the expression is a comma-expression, it must | ||
173 | be enclosed in parentheses. | ||
174 | |||
175 | |||
176 | Try statement | ||
177 | Catch_anonymous statement | ||
178 | |||
179 | When the value of the exception is not needed, a Try/Catch statement | ||
180 | can use Catch_anonymous instead of Catch (expression). | ||
181 | |||
182 | |||
183 | Everything below this point is for the benefit of the compiler. The | ||
184 | application programmer should pretend not to know any of it, because it | ||
185 | is subject to change. | ||
186 | |||
187 | ===*/ | ||
188 | |||
189 | |||
190 | #ifndef CEXCEPT_H | ||
191 | #define CEXCEPT_H | ||
192 | |||
193 | |||
194 | #include <setjmp.h> | ||
195 | |||
196 | #define define_exception_type(etype) \ | ||
197 | struct exception_context { \ | ||
198 | jmp_buf *penv; \ | ||
199 | int caught; \ | ||
200 | volatile struct { etype etmp; } v; \ | ||
201 | } | ||
202 | |||
203 | /* etmp must be volatile because the application might use automatic */ | ||
204 | /* storage for the_exception_context, and etmp is modified between */ | ||
205 | /* the calls to setjmp() and longjmp(). A wrapper struct is used to */ | ||
206 | /* avoid warnings about a duplicate volatile qualifier in case etype */ | ||
207 | /* already includes it. */ | ||
208 | |||
209 | #define init_exception_context(ec) ((void)((ec)->penv = 0)) | ||
210 | |||
211 | #define Try \ | ||
212 | { \ | ||
213 | jmp_buf *exception__prev, exception__env; \ | ||
214 | exception__prev = the_exception_context->penv; \ | ||
215 | the_exception_context->penv = &exception__env; \ | ||
216 | if (setjmp(exception__env) == 0) { \ | ||
217 | do | ||
218 | |||
219 | #define exception__catch(action) \ | ||
220 | while (the_exception_context->caught = 0, \ | ||
221 | the_exception_context->caught); \ | ||
222 | } \ | ||
223 | else { \ | ||
224 | the_exception_context->caught = 1; \ | ||
225 | } \ | ||
226 | the_exception_context->penv = exception__prev; \ | ||
227 | } \ | ||
228 | if (!the_exception_context->caught || action) { } \ | ||
229 | else | ||
230 | |||
231 | #define Catch(e) exception__catch(((e) = the_exception_context->v.etmp, 0)) | ||
232 | #define Catch_anonymous exception__catch(0) | ||
233 | |||
234 | /* Try ends with do, and Catch begins with while(0) and ends with */ | ||
235 | /* else, to ensure that Try/Catch syntax is similar to if/else */ | ||
236 | /* syntax. */ | ||
237 | /* */ | ||
238 | /* The 0 in while(0) is expressed as x=0,x in order to appease */ | ||
239 | /* compilers that warn about constant expressions inside while(). */ | ||
240 | /* Most compilers should still recognize that the condition is always */ | ||
241 | /* false and avoid generating code for it. */ | ||
242 | |||
243 | #define Throw \ | ||
244 | for (;; longjmp(*the_exception_context->penv, 1)) \ | ||
245 | the_exception_context->v.etmp = | ||
246 | |||
247 | |||
248 | #endif /* CEXCEPT_H */ | ||