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