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 #ifndef EXCEPTION_LIB
00040 #define EXCEPTION_LIB
00041
00042 #ifdef use_namespace
00043 namespace RBD_COMMON {
00044 #endif
00045
00046
00047 void Terminate();
00048
00049
00050
00051
00052 class Exception;
00053
00054 class Tracer
00055 {
00056 char* entry;
00057 Tracer* previous;
00058 public:
00059 Tracer(char*);
00060 ~Tracer();
00061 void ReName(char*);
00062 static void PrintTrace();
00063 static void AddTrace();
00064 static Tracer* last;
00065 friend class Exception;
00066 };
00067
00068
00069 class Exception
00070 {
00071 protected:
00072 static char* what_error;
00073 static int SoFar;
00074 static int LastOne;
00075 public:
00076 static void AddMessage(const char* a_what);
00077
00078 static void AddInt(int value);
00079 static unsigned long Select;
00080 Exception(const char* a_what = 0);
00081 static const char* what() { return what_error; }
00082
00083 };
00084
00085
00086 inline Tracer::Tracer(char* e)
00087 : entry(e), previous(last) { last = this; }
00088
00089 inline Tracer::~Tracer() { last = previous; }
00090
00091 inline void Tracer::ReName(char* e) { entry=e; }
00092
00093 #ifdef SimulateExceptions // SimulateExceptions
00094
00095 #include <setjmp.h>
00096
00097
00098
00099
00100
00101 class JumpItem;
00102 class Janitor;
00103
00104 class JumpBase
00105 {
00106 public:
00107 static JumpItem *jl;
00108 static jmp_buf env;
00109 };
00110
00111 class JumpItem
00112 {
00113 public:
00114 JumpItem *ji;
00115 jmp_buf env;
00116 Tracer* trace;
00117 Janitor* janitor;
00118 JumpItem() : ji(JumpBase::jl), trace(0), janitor(0)
00119 { JumpBase::jl = this; }
00120 ~JumpItem() { JumpBase::jl = ji; }
00121 };
00122
00123 void Throw();
00124
00125 inline void Throw(const Exception&) { Throw(); }
00126
00127 #define Try \
00128 if (!setjmp( JumpBase::jl->env )) { \
00129 JumpBase::jl->trace = Tracer::last; \
00130 JumpItem JI387256156;
00131
00132 #define ReThrow Throw()
00133
00134 #define Catch(EXCEPTION) \
00135 } else if (Exception::Select == EXCEPTION::Select) {
00136
00137 #define CatchAll } else
00138
00139 #define CatchAndThrow } else Throw();
00140
00141
00142
00143
00144 class Janitor
00145 {
00146 protected:
00147 static bool do_not_link;
00148 bool OnStack;
00149 public:
00150 Janitor* NextJanitor;
00151 virtual void CleanUp() {}
00152 Janitor();
00153 virtual ~Janitor();
00154 };
00155
00156
00157
00158
00159
00160
00161 class JanitorInitializer
00162 {
00163 public:
00164 JanitorInitializer();
00165 private:
00166 static int ref_count;
00167 };
00168
00169 static JanitorInitializer JanInit;
00170
00171 #endif // end of SimulateExceptions
00172
00173 #ifdef UseExceptions
00174
00175 #define Try try
00176 #define Throw(E) throw E
00177 #define ReThrow throw
00178 #define Catch catch
00179 #define CatchAll catch(...)
00180 #define CatchAndThrow {}
00181
00182 #endif // end of UseExceptions
00183
00184
00185 #ifdef DisableExceptions // Disable exceptions
00186
00187 #define Try {
00188 #define ReThrow Throw()
00189 #define Catch(EXCEPTION) } if (false) {
00190 #define CatchAll } if (false)
00191 #define CatchAndThrow }
00192
00193 inline void Throw() { Terminate(); }
00194 inline void Throw(const Exception&) { Terminate(); }
00195
00196
00197 #endif // end of DisableExceptions
00198
00199 #ifndef SimulateExceptions // ! SimulateExceptions
00200
00201 class Janitor
00202 {
00203 public:
00204 virtual void CleanUp() {}
00205 Janitor() {}
00206 virtual ~Janitor() {}
00207 };
00208
00209 #endif // end of ! SimulateExceptions
00210
00211
00212
00213
00214 #ifdef DO_FREE_CHECK // DO_FREE_CHECK
00215
00216
00217 class FreeCheck;
00218
00219 class FreeCheckLink
00220 {
00221 protected:
00222 FreeCheckLink* next;
00223 void* ClassStore;
00224 FreeCheckLink();
00225 virtual void Report()=0;
00226 friend class FreeCheck;
00227 };
00228
00229 class FCLClass : public FreeCheckLink
00230 {
00231 char* ClassName;
00232 FCLClass(void* t, char* name);
00233 void Report();
00234 friend class FreeCheck;
00235 };
00236
00237 class FCLRealArray : public FreeCheckLink
00238 {
00239 char* Operation;
00240 int size;
00241 FCLRealArray(void* t, char* o, int s);
00242 void Report();
00243 friend class FreeCheck;
00244 };
00245
00246 class FCLIntArray : public FreeCheckLink
00247 {
00248 char* Operation;
00249 int size;
00250 FCLIntArray(void* t, char* o, int s);
00251 void Report();
00252 friend class FreeCheck;
00253 };
00254
00255
00256 class FreeCheck
00257 {
00258 static FreeCheckLink* next;
00259 static int BadDelete;
00260 public:
00261 static void Register(void*, char*);
00262 static void DeRegister(void*, char*);
00263 static void RegisterR(void*, char*, int);
00264 static void DeRegisterR(void*, char*, int);
00265 static void RegisterI(void*, char*, int);
00266 static void DeRegisterI(void*, char*, int);
00267 static void Status();
00268 friend class FreeCheckLink;
00269 friend class FCLClass;
00270 friend class FCLRealArray;
00271 friend class FCLIntArray;
00272 };
00273
00274 #define FREE_CHECK(Class) \
00275 public: \
00276 void* operator new(size_t size) \
00277 { \
00278 void* t = ::operator new(size); FreeCheck::Register(t,#Class); \
00279 return t; \
00280 } \
00281 void operator delete(void* t) \
00282 { FreeCheck::DeRegister(t,#Class); ::operator delete(t); }
00283
00284
00285 #ifdef SimulateExceptions // SimulateExceptions
00286
00287 #define NEW_DELETE(Class) \
00288 public: \
00289 void* operator new(size_t size) \
00290 { \
00291 do_not_link=true; \
00292 void* t = ::operator new(size); FreeCheck::Register(t,#Class); \
00293 return t; \
00294 } \
00295 void operator delete(void* t) \
00296 { FreeCheck::DeRegister(t,#Class); ::operator delete(t); }
00297
00298
00299 #endif // end of SimulateExceptions
00300
00301
00302 #define MONITOR_REAL_NEW(Operation, Size, Pointer) \
00303 FreeCheck::RegisterR(Pointer, Operation, Size);
00304 #define MONITOR_INT_NEW(Operation, Size, Pointer) \
00305 FreeCheck::RegisterI(Pointer, Operation, Size);
00306 #define MONITOR_REAL_DELETE(Operation, Size, Pointer) \
00307 FreeCheck::DeRegisterR(Pointer, Operation, Size);
00308 #define MONITOR_INT_DELETE(Operation, Size, Pointer) \
00309 FreeCheck::DeRegisterI(Pointer, Operation, Size);
00310
00311 #else // DO_FREE_CHECK not defined
00312
00313 #define FREE_CHECK(Class) public:
00314 #define MONITOR_REAL_NEW(Operation, Size, Pointer) {}
00315 #define MONITOR_INT_NEW(Operation, Size, Pointer) {}
00316 #define MONITOR_REAL_DELETE(Operation, Size, Pointer) {}
00317 #define MONITOR_INT_DELETE(Operation, Size, Pointer) {}
00318
00319
00320 #ifdef SimulateExceptions // SimulateExceptions
00321
00322
00323 #define NEW_DELETE(Class) \
00324 public: \
00325 void* operator new(size_t size) \
00326 { do_not_link=true; void* t = ::operator new(size); return t; } \
00327 void operator delete(void* t) { ::operator delete(t); }
00328
00329 #endif // end of SimulateExceptions
00330
00331 #endif // end of ! DO_FREE_CHECK
00332
00333 #ifndef SimulateExceptions // ! SimulateExceptions
00334
00335 #define NEW_DELETE(Class) FREE_CHECK(Class)
00336
00337 #endif // end of ! SimulateExceptions
00338
00339
00340
00341
00342 class Logic_error : public Exception
00343 {
00344 public:
00345 static unsigned long Select;
00346 Logic_error(const char* a_what = 0);
00347 };
00348
00349 class Runtime_error : public Exception
00350 {
00351 public:
00352 static unsigned long Select;
00353 Runtime_error(const char* a_what = 0);
00354 };
00355
00356 class Domain_error : public Logic_error
00357 {
00358 public:
00359 static unsigned long Select;
00360 Domain_error(const char* a_what = 0);
00361 };
00362
00363 class Invalid_argument : public Logic_error
00364 {
00365 public:
00366 static unsigned long Select;
00367 Invalid_argument(const char* a_what = 0);
00368 };
00369
00370 class Length_error : public Logic_error
00371 {
00372 public:
00373 static unsigned long Select;
00374 Length_error(const char* a_what = 0);
00375 };
00376
00377 class Out_of_range : public Logic_error
00378 {
00379 public:
00380 static unsigned long Select;
00381 Out_of_range(const char* a_what = 0);
00382 };
00383
00384 class Bad_cast : public Logic_error
00385 {
00386 public:
00387 static unsigned long Select;
00388 Bad_cast(const char* a_what = 0);
00389 };
00390
00391 class Bad_typeid : public Logic_error
00392 {
00393 public:
00394 static unsigned long Select;
00395 Bad_typeid(const char* a_what = 0);
00396 };
00397
00398 class Range_error : public Runtime_error
00399 {
00400 public:
00401 static unsigned long Select;
00402 Range_error(const char* a_what = 0);
00403 };
00404
00405 class Overflow_error : public Runtime_error
00406 {
00407 public:
00408 static unsigned long Select;
00409 Overflow_error(const char* a_what = 0);
00410 };
00411
00412 class Bad_alloc : public Exception
00413 {
00414 public:
00415 static unsigned long Select;
00416 Bad_alloc(const char* a_what = 0);
00417 };
00418
00419 #ifdef use_namespace
00420 }
00421 #endif
00422
00423
00424 #endif // end of EXCEPTION_LIB
00425