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