myexcept.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006 #ifndef WANT_STREAM
00007 #define WANT_STREAM // include.h will get stream fns
00008 #endif
00009 #ifndef WANT_STRING
00010 #define WANT_STRING
00011 #endif
00012
00013 #include "include.h"
00014
00015
00016 #include "myexcept.h"
00017
00018 using namespace std;
00019
00020 #ifdef use_namespace
00021 namespace RBD_COMMON {
00022 #endif
00023
00024
00025
00026
00027
00028
00029 #ifdef SimulateExceptions
00030
00031 void Throw()
00032 {
00033 for (Janitor* jan = JumpBase::jl->janitor; jan; jan = jan->NextJanitor)
00034 jan->CleanUp();
00035 JumpItem* jx = JumpBase::jl->ji;
00036 if ( !jx ) { Terminate(); }
00037 JumpBase::jl = jx;
00038
00039 Tracer::last = JumpBase::jl->trace;
00040 longjmp(JumpBase::jl->env, 1);
00041 }
00042
00043 #endif // end of simulate exceptions
00044
00045
00046 unsigned long BaseException::Select;
00047 char* BaseException::what_error;
00048 int BaseException::SoFar;
00049 int BaseException::LastOne;
00050
00051 BaseException::BaseException(const char* a_what)
00052 {
00053 Select++; SoFar = 0;
00054 if (!what_error)
00055 {
00056 LastOne = 511;
00057 what_error = new char[512];
00058 if (!what_error)
00059 {
00060 LastOne = 0;
00061 what_error = const_cast<char*>("No heap space for exception message\n");
00062 }
00063 }
00064 AddMessage("\n\nAn exception has been thrown\n");
00065 AddMessage(a_what);
00066 if (a_what) Tracer::AddTrace();
00067 }
00068
00069 void BaseException::AddMessage(const char* a_what)
00070 {
00071 if (a_what)
00072 {
00073 int l = strlen(a_what); int r = LastOne - SoFar;
00074 if (l < r) { strcpy(what_error+SoFar, a_what); SoFar += l; }
00075 else if (r > 0)
00076 {
00077 strncpy(what_error+SoFar, a_what, r);
00078 what_error[LastOne] = 0;
00079 SoFar = LastOne;
00080 }
00081 }
00082 }
00083
00084 void BaseException::AddInt(int value)
00085 {
00086 bool negative;
00087 if (value == 0) { AddMessage("0"); return; }
00088 else if (value < 0) { value = -value; negative = true; }
00089 else negative = false;
00090 int n = 0; int v = value;
00091 while (v > 0) { v /= 10; n++; }
00092 if (negative) n++;
00093 if (LastOne-SoFar < n) { AddMessage("***"); return; }
00094
00095 SoFar += n; n = SoFar; what_error[n] = 0;
00096 while (value > 0)
00097 {
00098 int nv = value / 10; int rm = value - nv * 10; value = nv;
00099 what_error[--n] = (char)(rm + '0');
00100 }
00101 if (negative) what_error[--n] = '-';
00102 return;
00103 }
00104
00105 void Tracer::PrintTrace()
00106 {
00107 cout << "\n";
00108 for (Tracer* et = last; et; et=et->previous)
00109 cout << " * " << et->entry << "\n";
00110 }
00111
00112 void Tracer::AddTrace()
00113 {
00114 if (last)
00115 {
00116 BaseException::AddMessage("Trace: ");
00117 BaseException::AddMessage(last->entry);
00118 for (Tracer* et = last->previous; et; et=et->previous)
00119 {
00120 BaseException::AddMessage("; ");
00121 BaseException::AddMessage(et->entry);
00122 }
00123 BaseException::AddMessage(".\n");
00124 }
00125 }
00126
00127 #ifdef SimulateExceptions
00128
00129
00130 Janitor::Janitor()
00131 {
00132 if (do_not_link)
00133 {
00134 do_not_link = false; NextJanitor = 0; OnStack = false;
00135 #ifdef CLEAN_LIST
00136 cout << "Not added to clean-list " << (unsigned long)this << "\n";
00137 #endif
00138 }
00139 else
00140 {
00141 OnStack = true;
00142 #ifdef CLEAN_LIST
00143 cout << "Add to clean-list " << (unsigned long)this << "\n";
00144 #endif
00145 NextJanitor = JumpBase::jl->janitor; JumpBase::jl->janitor=this;
00146 }
00147 }
00148
00149 Janitor::~Janitor()
00150 {
00151
00152
00153 if (OnStack)
00154 {
00155 #ifdef CLEAN_LIST
00156 cout << "Delete from clean-list " << (unsigned long)this << "\n";
00157 #endif
00158 Janitor* lastjan = JumpBase::jl->janitor;
00159 if (this == lastjan) JumpBase::jl->janitor = NextJanitor;
00160 else
00161 {
00162 for (Janitor* jan = lastjan->NextJanitor; jan;
00163 jan = lastjan->NextJanitor)
00164 {
00165 if (jan==this)
00166 { lastjan->NextJanitor = jan->NextJanitor; return; }
00167 lastjan=jan;
00168 }
00169
00170 Throw(BaseException(
00171 "Cannot resolve memory linked list\nSee notes in myexcept.cpp for details\n"
00172 ));
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200 }
00201 }
00202 }
00203
00204 JumpItem* JumpBase::jl;
00205 jmp_buf JumpBase::env;
00206 bool Janitor::do_not_link;
00207
00208
00209 int JanitorInitializer::ref_count;
00210
00211 JanitorInitializer::JanitorInitializer()
00212 {
00213 if (ref_count++ == 0) new JumpItem;
00214
00215 }
00216
00217 #endif // end of SimulateExceptions
00218
00219 Tracer* Tracer::last;
00220
00221
00222 void Terminate()
00223 {
00224 cout << "\n\nThere has been an exception with no handler - exiting";
00225 const char* what = BaseException::getWhat();
00226 if (what) cout << what << "\n";
00227 exit(1);
00228 }
00229
00230
00231
00232 #ifdef DO_FREE_CHECK
00233
00234
00235 FreeCheckLink::FreeCheckLink() : next(FreeCheck::next)
00236 { FreeCheck::next = this; }
00237
00238 FCLClass::FCLClass(void* t, char* name) : ClassName(name) { ClassStore=t; }
00239
00240 FCLRealArray::FCLRealArray(void* t, char* o, int s)
00241 : Operation(o), size(s) { ClassStore=t; }
00242
00243 FCLIntArray::FCLIntArray(void* t, char* o, int s)
00244 : Operation(o), size(s) { ClassStore=t; }
00245
00246 FreeCheckLink* FreeCheck::next;
00247 int FreeCheck::BadDelete;
00248
00249 void FCLClass::Report()
00250 { cout << " " << ClassName << " " << (unsigned long)ClassStore << "\n"; }
00251
00252 void FCLRealArray::Report()
00253 {
00254 cout << " " << Operation << " " << (unsigned long)ClassStore <<
00255 " " << size << "\n";
00256 }
00257
00258 void FCLIntArray::Report()
00259 {
00260 cout << " " << Operation << " " << (unsigned long)ClassStore <<
00261 " " << size << "\n";
00262 }
00263
00264 void FreeCheck::Register(void* t, char* name)
00265 {
00266 FCLClass* f = new FCLClass(t,name);
00267 if (!f) { cout << "Out of memory in FreeCheck\n"; exit(1); }
00268 #ifdef REG_DEREG
00269 cout << "Registering " << name << " " << (unsigned long)t << "\n";
00270 #endif
00271 }
00272
00273 void FreeCheck::RegisterR(void* t, char* o, int s)
00274 {
00275 FCLRealArray* f = new FCLRealArray(t,o,s);
00276 if (!f) { cout << "Out of memory in FreeCheck\n"; exit(1); }
00277 #ifdef REG_DEREG
00278 cout << o << " " << s << " " << (unsigned long)t << "\n";
00279 #endif
00280 }
00281
00282 void FreeCheck::RegisterI(void* t, char* o, int s)
00283 {
00284 FCLIntArray* f = new FCLIntArray(t,o,s);
00285 if (!f) { cout << "Out of memory in FreeCheck\n"; exit(1); }
00286 #ifdef REG_DEREG
00287 cout << o << " " << s << " " << (unsigned long)t << "\n";
00288 #endif
00289 }
00290
00291 void FreeCheck::DeRegister(void* t, char* name)
00292 {
00293 FreeCheckLink* last = 0;
00294 #ifdef REG_DEREG
00295 cout << "Deregistering " << name << " " << (unsigned long)t << "\n";
00296 #endif
00297 for (FreeCheckLink* fcl = next; fcl; fcl = fcl->next)
00298 {
00299 if (fcl->ClassStore==t)
00300 {
00301 if (last) last->next = fcl->next; else next = fcl->next;
00302 delete fcl; return;
00303 }
00304 last = fcl;
00305 }
00306 cout << "\nRequest to delete non-existent object of class and location:\n";
00307 cout << " " << name << " " << (unsigned long)t << "\n";
00308 BadDelete++;
00309 Tracer::PrintTrace();
00310 cout << "\n";
00311 }
00312
00313 void FreeCheck::DeRegisterR(void* t, char* o, int s)
00314 {
00315 FreeCheckLink* last = 0;
00316 #ifdef REG_DEREG
00317 cout << o << " " << s << " " << (unsigned long)t << "\n";
00318 #endif
00319 for (FreeCheckLink* fcl = next; fcl; fcl = fcl->next)
00320 {
00321 if (fcl->ClassStore==t)
00322 {
00323 if (last) last->next = fcl->next; else next = fcl->next;
00324 if (s >= 0 && ((FCLRealArray*)fcl)->size != s)
00325 {
00326 cout << "\nArray sizes do not agree:\n";
00327 cout << " " << o << " " << (unsigned long)t
00328 << " " << ((FCLRealArray*)fcl)->size << " " << s << "\n";
00329 Tracer::PrintTrace();
00330 cout << "\n";
00331 }
00332 delete fcl; return;
00333 }
00334 last = fcl;
00335 }
00336 cout << "\nRequest to delete non-existent real array:\n";
00337 cout << " " << o << " " << (unsigned long)t << " " << s << "\n";
00338 BadDelete++;
00339 Tracer::PrintTrace();
00340 cout << "\n";
00341 }
00342
00343 void FreeCheck::DeRegisterI(void* t, char* o, int s)
00344 {
00345 FreeCheckLink* last = 0;
00346 #ifdef REG_DEREG
00347 cout << o << " " << s << " " << (unsigned long)t << "\n";
00348 #endif
00349 for (FreeCheckLink* fcl = next; fcl; fcl = fcl->next)
00350 {
00351 if (fcl->ClassStore==t)
00352 {
00353 if (last) last->next = fcl->next; else next = fcl->next;
00354 if (s >= 0 && ((FCLIntArray*)fcl)->size != s)
00355 {
00356 cout << "\nArray sizes do not agree:\n";
00357 cout << " " << o << " " << (unsigned long)t
00358 << " " << ((FCLIntArray*)fcl)->size << " " << s << "\n";
00359 Tracer::PrintTrace();
00360 cout << "\n";
00361 }
00362 delete fcl; return;
00363 }
00364 last = fcl;
00365 }
00366 cout << "\nRequest to delete non-existent int array:\n";
00367 cout << " " << o << " " << (unsigned long)t << " " << s << "\n";
00368 BadDelete++;
00369 Tracer::PrintTrace();
00370 cout << "\n";
00371 }
00372
00373 void FreeCheck::Status()
00374 {
00375 if (next)
00376 {
00377 cout << "\nObjects of the following classes remain undeleted:\n";
00378 for (FreeCheckLink* fcl = next; fcl; fcl = fcl->next) fcl->Report();
00379 cout << "\n";
00380 }
00381 else cout << "\nNo objects remain undeleted\n\n";
00382 if (BadDelete)
00383 {
00384 cout << "\nThere were " << BadDelete <<
00385 " requests to delete non-existent items\n\n";
00386 }
00387 }
00388
00389 #endif // end of DO_FREE_CHECK
00390
00391
00392
00393 Logic_error::Logic_error(const char* a_what) : BaseException()
00394 {
00395 Select = BaseException::Select;
00396 AddMessage("Logic error:- "); AddMessage(a_what);
00397 if (a_what) Tracer::AddTrace();
00398 }
00399
00400 Runtime_error::Runtime_error(const char* a_what)
00401 : BaseException()
00402 {
00403 Select = BaseException::Select;
00404 AddMessage("Runtime error:- "); AddMessage(a_what);
00405 if (a_what) Tracer::AddTrace();
00406 }
00407
00408 Domain_error::Domain_error(const char* a_what) : Logic_error()
00409 {
00410 Select = BaseException::Select;
00411 AddMessage("domain error\n"); AddMessage(a_what);
00412 if (a_what) Tracer::AddTrace();
00413 }
00414
00415 Invalid_argument::Invalid_argument(const char* a_what) : Logic_error()
00416 {
00417 Select = BaseException::Select;
00418 AddMessage("invalid argument\n"); AddMessage(a_what);
00419 if (a_what) Tracer::AddTrace();
00420 }
00421
00422 Length_error::Length_error(const char* a_what) : Logic_error()
00423 {
00424 Select = BaseException::Select;
00425 AddMessage("length error\n"); AddMessage(a_what);
00426 if (a_what) Tracer::AddTrace();
00427 }
00428
00429 Out_of_range::Out_of_range(const char* a_what) : Logic_error()
00430 {
00431 Select = BaseException::Select;
00432 AddMessage("out of range\n"); AddMessage(a_what);
00433 if (a_what) Tracer::AddTrace();
00434 }
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450 Range_error::Range_error(const char* a_what) : Runtime_error()
00451 {
00452 Select = BaseException::Select;
00453 AddMessage("range error\n"); AddMessage(a_what);
00454 if (a_what) Tracer::AddTrace();
00455 }
00456
00457 Overflow_error::Overflow_error(const char* a_what) : Runtime_error()
00458 {
00459 Select = BaseException::Select;
00460 AddMessage("overflow error\n"); AddMessage(a_what);
00461 if (a_what) Tracer::AddTrace();
00462 }
00463
00464 Bad_alloc::Bad_alloc(const char* a_what) : BaseException()
00465 {
00466 Select = BaseException::Select;
00467 AddMessage("bad allocation\n"); AddMessage(a_what);
00468 if (a_what) Tracer::AddTrace();
00469 }
00470
00471
00472
00473
00474 unsigned long Logic_error::Select;
00475 unsigned long Runtime_error::Select;
00476 unsigned long Domain_error::Select;
00477 unsigned long Invalid_argument::Select;
00478 unsigned long Length_error::Select;
00479 unsigned long Out_of_range::Select;
00480
00481
00482 unsigned long Range_error::Select;
00483 unsigned long Overflow_error::Select;
00484 unsigned long Bad_alloc::Select;
00485
00486 #ifdef use_namespace
00487 }
00488 #endif
00489
00490