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