00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 #include <stdio.h>
00100 #include <stdlib.h>
00101 #include <string.h>
00102
00103 #include "arithmetique.h"
00104
00105
00106
00107
00108
00109 unsigned int overflow_error = 1;
00110 unsigned int simplex_arithmetic_error = 2;
00111 unsigned int user_exception_error = 4;
00112 unsigned int parser_exception_error = 8;
00113 unsigned int timeout_error = 16;
00114
00115
00116 unsigned int any_exception_error = ~0;
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 #ifndef HAVE_BOOLEAN
00127 typedef int boolean;
00128 #endif
00129 #ifndef FALSE
00130 #define FALSE 0
00131 #endif
00132 #ifndef TRUE
00133 #define TRUE 1
00134 #endif
00135
00136 const char *get_exception_name(unsigned int exception)
00137 {
00138 if (exception==overflow_error)
00139 return "overflow_error exception";
00140 if (exception==simplex_arithmetic_error)
00141 return "simplex_arithmetic_error exception";
00142 if (exception==user_exception_error)
00143 return "user_exception_error exception";
00144 if (exception==parser_exception_error)
00145 return "parser_exception_error exception";
00146 if (exception==timeout_error)
00147 return "timeout_error exception";
00148 if (exception==any_exception_error)
00149 return "all exceptions mask";
00150
00151 return "unknown or mixed exception";
00152 }
00153
00154
00155
00156 unsigned int the_last_just_thrown_exception = 0;
00157
00158
00159
00160 static int linear_exception_debug_mode = FALSE;
00161 static unsigned int linear_exception_verbose = 1 | 2 | 16 ;
00162
00163
00164
00165 typedef struct
00166 {
00167
00168
00169 int what;
00170
00171
00172
00173 jmp_buf where;
00174
00175
00176
00177 const char * function;
00178 const char * file;
00179 int line;
00180 }
00181 linear_exception_holder;
00182
00183
00184
00185
00186
00187 #define MAX_STACKED_CONTEXTS 64
00188 static linear_exception_holder exception_stack[MAX_STACKED_CONTEXTS];
00189 static int exception_index = 0;
00190
00191
00192
00193 static exception_callback_t push_callback = NULL;
00194 static exception_callback_t pop_callback = NULL;
00195
00196 void set_exception_callbacks(exception_callback_t push,
00197 exception_callback_t pop)
00198 {
00199 if (push_callback!=NULL || pop_callback!=NULL)
00200 {
00201 fprintf(stderr, "exception callbacks already defined! (%p, %p)\n",
00202 push_callback, pop_callback);
00203 abort();
00204 }
00205
00206 push_callback = push;
00207 pop_callback = pop;
00208 }
00209
00210
00211
00212 int linear_number_of_exception_thrown = 0;
00213
00214
00215
00216 void dump_exception_stack_to_file(FILE * f)
00217 {
00218 int i;
00219 fprintf(f, "[dump_exception_stack_to_file] size=%d\n", exception_index);
00220 for (i=0; i<exception_index; i++)
00221 {
00222 fprintf(f,
00223 "%d: [%s:%d in %s (%d)]\n",
00224 i,
00225 exception_stack[i].file,
00226 exception_stack[i].line,
00227 exception_stack[i].function,
00228 exception_stack[i].what);
00229 }
00230 fprintf(f, "\n");
00231 }
00232
00233 void dump_exception_stack()
00234 {
00235 dump_exception_stack_to_file(stderr);
00236 }
00237
00238 #define exception_debug_message(type) \
00239 fprintf(stderr, "%s[%s:%d %s (%d)/%d]\n", \
00240 type, file, line, function, what, exception_index)
00241
00242 #define exception_debug_trace(type) \
00243 if (linear_exception_debug_mode) { exception_debug_message(type); }
00244
00245
00246
00247
00248 jmp_buf *
00249 push_exception_on_stack(
00250 int what,
00251 const char * function,
00252 const char * file,
00253 int line)
00254 {
00255 exception_debug_trace("PUSH ");
00256
00257 if (exception_index==MAX_STACKED_CONTEXTS)
00258 {
00259 exception_debug_message("push");
00260 fprintf(stderr, "exception stack overflow\n");
00261 dump_exception_stack();
00262 abort();
00263 }
00264
00265 if (push_callback) push_callback(file, function, line);
00266
00267 the_last_just_thrown_exception = 0;
00268
00269 exception_stack[exception_index].what = what;
00270 exception_stack[exception_index].function = function;
00271 exception_stack[exception_index].file = file;
00272 exception_stack[exception_index].line = line;
00273
00274 return & exception_stack[exception_index++].where;
00275 }
00276
00277 #if !defined(same_string_p)
00278 #define same_string_p(s1, s2) (strcmp((s1),(s2))==0)
00279 #endif
00280
00281
00282
00283
00284 void
00285 pop_exception_from_stack(
00286 int what,
00287 const char * function,
00288 const char * file,
00289 int line)
00290 {
00291 exception_debug_trace("POP ");
00292
00293 if (exception_index==0)
00294 {
00295 exception_debug_message("pop");
00296 fprintf(stderr, "exception stack underflow\n");
00297 dump_exception_stack();
00298 abort();
00299 }
00300
00301 if (pop_callback) pop_callback(file, function, line);
00302
00303 exception_index--;
00304 the_last_just_thrown_exception = 0;
00305
00306 if ((exception_stack[exception_index].what != what) ||
00307 !same_string_p(exception_stack[exception_index].file, file) ||
00308 !same_string_p(exception_stack[exception_index].function, function))
00309 {
00310 exception_debug_message("pop");
00311 fprintf(stderr,
00312 "exception stack mismatch at depth=%d:\n"
00313 " CATCH: %s:%d in %s (%d)\n"
00314 " UNCATCH: %s:%d in %s (%d)\n",
00315 exception_index,
00316 exception_stack[exception_index].file,
00317 exception_stack[exception_index].line,
00318 exception_stack[exception_index].function,
00319 exception_stack[exception_index].what,
00320 file, line, function, what);
00321 dump_exception_stack();
00322 abort();
00323 }
00324 }
00325
00326
00327
00328
00329 void throw_exception(
00330 int what,
00331 const char * function,
00332 const char * file,
00333 int line)
00334 {
00335 int i;
00336
00337 exception_debug_trace("THROW");
00338
00339 the_last_just_thrown_exception = what;
00340
00341 for (i=exception_index-1; i>=0; i--)
00342 {
00343 if (pop_callback)
00344
00345 pop_callback(exception_stack[i].file,
00346 exception_stack[i].function,
00347 exception_stack[i].line);
00348
00349 if (exception_stack[i].what & what)
00350 {
00351 exception_index = i;
00352 linear_number_of_exception_thrown++;
00353
00354 if (linear_exception_debug_mode)
00355 fprintf(stderr, "---->[%s:%d %s (%d)/%d]\n",
00356 exception_stack[i].file,
00357 exception_stack[i].line,
00358 exception_stack[i].function,
00359 exception_stack[i].what,
00360 i);
00361
00362
00363 if (linear_exception_verbose & what)
00364 fprintf(stderr, "exception %d/%d: %s(%s:%d) -> %s(%s:%d)\n",
00365 what, exception_stack[i].what,
00366 function, file, line,
00367 exception_stack[i].function,
00368 exception_stack[i].file,
00369 exception_stack[i].line);
00370
00371 longjmp(exception_stack[i].where, 0);
00372 }
00373 }
00374
00375
00376 exception_debug_message("throw");
00377 fprintf(stderr,
00378 "exception not found in stack:\n"
00379 "an exception was THROWN without a proper matching CATCH\n");
00380 dump_exception_stack();
00381 abort();
00382 }
00383
00384 void linear_initialize_exception_stack(
00385 unsigned int verbose_exceptions,
00386 exception_callback_t push,
00387 exception_callback_t pop)
00388 {
00389 linear_exception_verbose = verbose_exceptions;
00390 set_exception_callbacks(push, pop);
00391 }