2 $Id: errors.c,v 1.6 2006/03/15 19:59:37 verdoolaege Exp $
5 See "arithmetic_errors.h".
8 Revision 1.6 2006/03/15 19:59:37 verdoolaege
9 arith: add some missing consts
11 Revision 1.5 2004/08/31 18:01:56 verdoolaege
14 Revision 1.4 2004/02/11 10:19:54 verdoolaege
17 Revision 1.3 2004/02/08 21:53:27 kienhuis
18 Update from Fabien Coelho, via Bart Kienhuis
20 I've updated here in the C3/Linear library the arithmetic_error
21 package that I developped (with others) to handle exceptions in C.
22 It adds a simple callback feature which is needed for pips here.
23 If you do not use it, it should not harm;-)
25 Revision 1.27 2003/09/04 09:40:37 coelho
29 Revision 1.26 2003/09/03 14:05:20 coelho
30 push/pop callbacks called.
32 Revision 1.20 2003/08/18 09:55:09 coelho
33 get_exception_name added...
35 Revision 1.19 2003/06/13 13:59:07 coelho
38 Revision 1.18 2003/06/13 13:54:47 coelho
41 Revision 1.17 2002/04/02 08:44:54 coelho
44 Revision 1.16 2000/10/27 13:26:03 ancourt
45 exception_thrown -> linear_number_of_exception_thrown
47 Revision 1.15 2000/07/27 15:21:55 coelho
50 Revision 1.14 2000/07/27 14:59:59 coelho
53 Revision 1.13 2000/07/26 08:41:23 coelho
54 the_last_just_thrown_exception management added.
56 Revision 1.12 1998/10/26 18:48:34 coelho
59 Revision 1.11 1998/10/26 14:38:06 coelho
62 Revision 1.10 1998/10/26 14:35:47 coelho
65 Revision 1.9 1998/10/24 15:36:22 coelho
66 better exception error messages...
68 Revision 1.8 1998/10/24 15:19:17 coelho
71 Revision 1.7 1998/10/24 14:31:13 coelho
72 new stack implementation.
73 checks for matching catch/uncatch.
76 Revision 1.6 1998/10/24 09:31:06 coelho
86 #include "arithmetique.h"
88 /* global constants to designate exceptions.
89 to be put in the type field bellow.
90 cproto 4.6 does not line 'const'...
92 unsigned int overflow_error
= 1;
93 unsigned int simplex_arithmetic_error
= 2;
94 unsigned int user_exception_error
= 4;
95 unsigned int parser_exception_error
= 8;
96 unsigned int timeout_error
= 16;
99 unsigned int any_exception_error
= ~0;
103 * On a few systems, type boolean and/or its values FALSE, TRUE may appear
104 * in standard header files. Or you may have conflicts with application-
105 * specific header files that you want to include together with these files.
106 * Defining HAVE_BOOLEAN before including jpeglib.h should make it work.
112 #ifndef FALSE /* in case these macros already exist */
113 #define FALSE 0 /* values of boolean */
119 const char *get_exception_name(unsigned int exception
)
121 if (exception
==overflow_error
)
122 return "overflow_error exception";
123 if (exception
==simplex_arithmetic_error
)
124 return "simplex_arithmetic_error exception";
125 if (exception
==user_exception_error
)
126 return "user_exception_error exception";
127 if (exception
==parser_exception_error
)
128 return "parser_exception_error exception";
129 if (exception
==timeout_error
)
130 return "timeout_error exception";
131 if (exception
==any_exception_error
)
132 return "all exceptions mask";
134 return "unknown or mixed exception";
137 /* keep track of last thrown exception for RETHROW()
139 unsigned int the_last_just_thrown_exception
= 0;
141 /* whether to run in debug mode (that is to trace catch/uncatch/throw)
143 static int linear_exception_debug_mode
= FALSE
;
144 static unsigned int linear_exception_verbose
= 1 | 2 | 16 ;
146 /* A structure for the exception stack.
158 /* location of the CATCH to be matched against the UNCATCH.
160 const char * function
;
164 linear_exception_holder
;
168 current index (next available bucket)
170 #define MAX_STACKED_CONTEXTS 64
171 static linear_exception_holder exception_stack
[MAX_STACKED_CONTEXTS
];
172 static int exception_index
= 0;
176 static exception_callback_t push_callback
= NULL
;
177 static exception_callback_t pop_callback
= NULL
;
179 void set_exception_callbacks(exception_callback_t push
,
180 exception_callback_t pop
)
182 if (push_callback
!=NULL
|| pop_callback
!=NULL
)
184 fprintf(stderr
, "exception callbacks already defined! (%p, %p)\n",
185 push_callback
, pop_callback
);
189 push_callback
= push
;
193 /* total number of exceptions thrown, for statistics.
195 int linear_number_of_exception_thrown
= 0;
199 void dump_exception_stack_to_file(FILE * f
)
202 fprintf(f
, "[dump_exception_stack_to_file] size=%d\n", exception_index
);
203 for (i
=0; i
<exception_index
; i
++)
206 "%d: [%s:%d in %s (%d)]\n",
208 exception_stack
[i
].file
,
209 exception_stack
[i
].line
,
210 exception_stack
[i
].function
,
211 exception_stack
[i
].what
);
216 void dump_exception_stack()
218 dump_exception_stack_to_file(stderr
);
221 #define exception_debug_message(type) \
222 fprintf(stderr, "%s[%s:%d %s (%d)/%d]\n", \
223 type, file, line, function, what, exception_index)
225 #define exception_debug_trace(type) \
226 if (linear_exception_debug_mode) { exception_debug_message(type); }
229 /* push a what exception on stack.
232 push_exception_on_stack(
234 const char * function
,
238 exception_debug_trace("PUSH ");
240 if (exception_index
==MAX_STACKED_CONTEXTS
)
242 exception_debug_message("push");
243 fprintf(stderr
, "exception stack overflow\n");
244 dump_exception_stack();
248 if (push_callback
) push_callback(file
, function
, line
);
250 the_last_just_thrown_exception
= 0;
252 exception_stack
[exception_index
].what
= what
;
253 exception_stack
[exception_index
].function
= function
;
254 exception_stack
[exception_index
].file
= file
;
255 exception_stack
[exception_index
].line
= line
;
257 return & exception_stack
[exception_index
++].where
;
260 #if !defined(same_string_p)
261 #define same_string_p(s1, s2) (strcmp((s1),(s2))==0)
264 /* pop a what exception.
265 check for any mismatch!
268 pop_exception_from_stack(
270 const char * function
,
274 exception_debug_trace("POP ");
276 if (exception_index
==0)
278 exception_debug_message("pop");
279 fprintf(stderr
, "exception stack underflow\n");
280 dump_exception_stack();
284 if (pop_callback
) pop_callback(file
, function
, line
);
287 the_last_just_thrown_exception
= 0;
289 if ((exception_stack
[exception_index
].what
!= what
) ||
290 !same_string_p(exception_stack
[exception_index
].file
, file
) ||
291 !same_string_p(exception_stack
[exception_index
].function
, function
))
293 exception_debug_message("pop");
295 "exception stack mismatch at depth=%d:\n"
296 " CATCH: %s:%d in %s (%d)\n"
297 " UNCATCH: %s:%d in %s (%d)\n",
299 exception_stack
[exception_index
].file
,
300 exception_stack
[exception_index
].line
,
301 exception_stack
[exception_index
].function
,
302 exception_stack
[exception_index
].what
,
303 file
, line
, function
, what
);
304 dump_exception_stack();
309 /* throws an exception of a given type by searching for
310 the specified 'what' in the current exception stack.
312 void throw_exception(
314 const char * function
,
320 exception_debug_trace("THROW");
322 the_last_just_thrown_exception
= what
; /* for rethrow */
324 for (i
=exception_index
-1; i
>=0; i
--)
327 /* pop with push parameters! */
328 pop_callback(exception_stack
[i
].file
,
329 exception_stack
[i
].function
,
330 exception_stack
[i
].line
);
332 if (exception_stack
[i
].what
& what
)
335 linear_number_of_exception_thrown
++;
337 if (linear_exception_debug_mode
)
338 fprintf(stderr
, "---->[%s:%d %s (%d)/%d]\n",
339 exception_stack
[i
].file
,
340 exception_stack
[i
].line
,
341 exception_stack
[i
].function
,
342 exception_stack
[i
].what
,
345 /* trace some exceptions... */
346 if (linear_exception_verbose
& what
)
347 fprintf(stderr
, "exception %d/%d: %s(%s:%d) -> %s(%s:%d)\n",
348 what
, exception_stack
[i
].what
,
349 function
, file
, line
,
350 exception_stack
[i
].function
,
351 exception_stack
[i
].file
,
352 exception_stack
[i
].line
);
354 longjmp(exception_stack
[i
].where
, 0);
359 exception_debug_message("throw");
361 "exception not found in stack:\n"
362 "an exception was THROWN without a proper matching CATCH\n");
363 dump_exception_stack();
367 void linear_initialize_exception_stack(
368 unsigned int verbose_exceptions
,
369 exception_callback_t push
,
370 exception_callback_t pop
)
372 linear_exception_verbose
= verbose_exceptions
;
373 set_exception_callbacks(push
, pop
);