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