myexcept.cpp
Go to the documentation of this file.
1 
12 
13 // Copyright (C) 1993,4,6: R B Davies
14 
15 
16 #define WANT_STREAM // include.h will get stream fns
17 #define WANT_STRING
18 
19 #include "include.h" // include standard files
20 
21 
22 #include "myexcept.h" // for exception handling
23 
24 #ifdef use_namespace
25 namespace RBD_COMMON {
26 #endif
27 
28 
29 //#define REG_DEREG // for print out uses of new/delete
30 //#define CLEAN_LIST // to print entries being added to
31  // or deleted from cleanup list
32 
33 #ifdef SimulateExceptions
34 
35 void Throw()
36 {
37  for (Janitor* jan = JumpBase::jl->janitor; jan; jan = jan->NextJanitor)
38  jan->CleanUp();
39  JumpItem* jx = JumpBase::jl->ji; // previous jumpbase;
40  if ( !jx ) { Terminate(); } // jl was initial JumpItem
41  JumpBase::jl = jx; // drop down a level; cannot be in front
42  // of previous line
43  Tracer::last = JumpBase::jl->trace;
44  longjmp(JumpBase::jl->env, 1);
45 }
46 
47 #endif // end of simulate exceptions
48 
49 
50 unsigned long BaseException::Select;
54 
55 BaseException::BaseException(const char* a_what)
56 {
57  Select++; SoFar = 0;
58  if (!what_error) // make space for exception message
59  {
60  LastOne = 511;
61  what_error = new char[512];
62  if (!what_error) // fail to make space
63  {
64  LastOne = 0;
65  what_error = (char *)"No heap space for exception message\n";
66  }
67  }
68  AddMessage("\n\nAn exception has been thrown\n");
69  AddMessage(a_what);
70  if (a_what) Tracer::AddTrace();
71 }
72 
73 void BaseException::AddMessage(const char* a_what)
74 {
75  if (a_what)
76  {
77  int l = strlen(a_what); int r = LastOne - SoFar;
78  if (l < r) { strcpy(what_error+SoFar, a_what); SoFar += l; }
79  else if (r > 0)
80  {
81  strncpy(what_error+SoFar, a_what, r);
82  what_error[LastOne] = 0;
83  SoFar = LastOne;
84  }
85  }
86 }
87 
88 void BaseException::AddInt(int value)
89 {
90  bool negative;
91  if (value == 0) { AddMessage("0"); return; }
92  else if (value < 0) { value = -value; negative = true; }
93  else negative = false;
94  int n = 0; int v = value; // how many digits will we need?
95  while (v > 0) { v /= 10; n++; }
96  if (negative) n++;
97  if (LastOne-SoFar < n) { AddMessage("***"); return; }
98 
99  SoFar += n; n = SoFar; what_error[n] = 0;
100  while (value > 0)
101  {
102  int nv = value / 10; int rm = value - nv * 10; value = nv;
103  what_error[--n] = (char)(rm + '0');
104  }
105  if (negative) what_error[--n] = '-';
106  return;
107 }
108 
110 {
111  cout << "\n";
112  for (Tracer* et = last; et; et=et->previous)
113  cout << " * " << et->entry << "\n";
114 }
115 
117 {
118  if (last)
119  {
120  BaseException::AddMessage("Trace: ");
121  BaseException::AddMessage(last->entry);
122  for (Tracer* et = last->previous; et; et=et->previous)
123  {
125  BaseException::AddMessage(et->entry);
126  }
128  }
129 }
130 
131 #ifdef SimulateExceptions
132 
133 
135 {
136  if (do_not_link)
137  {
138  do_not_link = false; NextJanitor = 0; OnStack = false;
139 #ifdef CLEAN_LIST
140  cout << "Not added to clean-list " << (unsigned long)this << "\n";
141 #endif
142  }
143  else
144  {
145  OnStack = true;
146 #ifdef CLEAN_LIST
147  cout << "Add to clean-list " << (unsigned long)this << "\n";
148 #endif
149  NextJanitor = JumpBase::jl->janitor; JumpBase::jl->janitor=this;
150  }
151 }
152 
154 {
155  // expect the item to be deleted to be first on list
156  // but must be prepared to search list
157  if (OnStack)
158  {
159 #ifdef CLEAN_LIST
160  cout << "Delete from clean-list " << (unsigned long)this << "\n";
161 #endif
162  Janitor* lastjan = JumpBase::jl->janitor;
163  if (this == lastjan) JumpBase::jl->janitor = NextJanitor;
164  else
165  {
166  for (Janitor* jan = lastjan->NextJanitor; jan;
167  jan = lastjan->NextJanitor)
168  {
169  if (jan==this)
170  { lastjan->NextJanitor = jan->NextJanitor; return; }
171  lastjan=jan;
172  }
173 
175 "Cannot resolve memory linked list\nSee notes in myexcept.cpp for details\n"
176  ));
177 
178 
179 // This message occurs when a call to ~Janitor() occurs, apparently
180 // without a corresponding call to Janitor(). This could happen if my
181 // way of deciding whether a constructor is being called by new
182 // fails.
183 
184 // It may happen if you are using my simulated exceptions and also have
185 // your compiler s exceptions turned on.
186 
187 // It can also happen if you have a class derived from Janitor
188 // which does not include a copy constructor [ eg X(const &X) ].
189 // Possibly also if delete is applied an object on the stack (ie not
190 // called by new). Otherwise, it is a bug in myexcept or your compiler.
191 // If you do not #define TEMPS_DESTROYED_QUICKLY you will get this
192 // error with Microsoft C 7.0. There are probably situations where
193 // you will get this when you do define TEMPS_DESTROYED_QUICKLY. This
194 // is a bug in MSC. Beware of "operator" statements for defining
195 // conversions; particularly for converting from a Base class to a
196 // Derived class.
197 
198 // You may get away with simply deleting this error message and Throw
199 // statement if you can not find a better way of overcoming the
200 // problem. In any case please tell me if you get this error message,
201 // particularly for compilers apart from Microsoft C 7.0.
202 
203 
204  }
205  }
206 }
207 
208 JumpItem* JumpBase::jl; // will be set to zero
209 jmp_buf JumpBase::env;
210 bool Janitor::do_not_link; // will be set to false
211 
212 
213 int JanitorInitializer::ref_count;
214 
215 JanitorInitializer::JanitorInitializer()
216 {
217  if (ref_count++ == 0) new JumpItem;
218  // need JumpItem at head of list
219 }
220 
221 #endif // end of SimulateExceptions
222 
223 Tracer* Tracer::last; // will be set to zero
224 
225 
226 void Terminate()
227 {
228  cout << "\n\nThere has been an exception with no handler - exiting";
229  const char* what = BaseException::what();
230  if (what) cout << what << "\n";
231  exit(1);
232 }
233 
234 
235 
236 #ifdef DO_FREE_CHECK
237 // Routines for tracing whether new and delete calls are balanced
238 
239 FreeCheckLink::FreeCheckLink() : next(FreeCheck::next)
240  { FreeCheck::next = this; }
241 
242 FCLClass::FCLClass(void* t, char* name) : ClassName(name) { ClassStore=t; }
243 
244 FCLRealArray::FCLRealArray(void* t, char* o, int s)
245  : Operation(o), size(s) { ClassStore=t; }
246 
247 FCLIntArray::FCLIntArray(void* t, char* o, int s)
248  : Operation(o), size(s) { ClassStore=t; }
249 
250 FreeCheckLink* FreeCheck::next;
251 int FreeCheck::BadDelete;
252 
253 void FCLClass::Report()
254 { cout << " " << ClassName << " " << (unsigned long)ClassStore << "\n"; }
255 
256 void FCLRealArray::Report()
257 {
258  cout << " " << Operation << " " << (unsigned long)ClassStore <<
259  " " << size << "\n";
260 }
261 
262 void FCLIntArray::Report()
263 {
264  cout << " " << Operation << " " << (unsigned long)ClassStore <<
265  " " << size << "\n";
266 }
267 
268 void FreeCheck::Register(void* t, char* name)
269 {
270  FCLClass* f = new FCLClass(t,name);
271  if (!f) { cout << "Out of memory in FreeCheck\n"; exit(1); }
272 #ifdef REG_DEREG
273  cout << "Registering " << name << " " << (unsigned long)t << "\n";
274 #endif
275 }
276 
277 void FreeCheck::RegisterR(void* t, char* o, int s)
278 {
279  FCLRealArray* f = new FCLRealArray(t,o,s);
280  if (!f) { cout << "Out of memory in FreeCheck\n"; exit(1); }
281 #ifdef REG_DEREG
282  cout << o << " " << s << " " << (unsigned long)t << "\n";
283 #endif
284 }
285 
286 void FreeCheck::RegisterI(void* t, char* o, int s)
287 {
288  FCLIntArray* f = new FCLIntArray(t,o,s);
289  if (!f) { cout << "Out of memory in FreeCheck\n"; exit(1); }
290 #ifdef REG_DEREG
291  cout << o << " " << s << " " << (unsigned long)t << "\n";
292 #endif
293 }
294 
295 void FreeCheck::DeRegister(void* t, char* name)
296 {
297  FreeCheckLink* last = 0;
298 #ifdef REG_DEREG
299  cout << "Deregistering " << name << " " << (unsigned long)t << "\n";
300 #endif
301  for (FreeCheckLink* fcl = next; fcl; fcl = fcl->next)
302  {
303  if (fcl->ClassStore==t)
304  {
305  if (last) last->next = fcl->next; else next = fcl->next;
306  delete fcl; return;
307  }
308  last = fcl;
309  }
310  cout << "\nRequest to delete non-existent object of class and location:\n";
311  cout << " " << name << " " << (unsigned long)t << "\n";
312  BadDelete++;
314  cout << "\n";
315 }
316 
317 void FreeCheck::DeRegisterR(void* t, char* o, int s)
318 {
319  FreeCheckLink* last = 0;
320 #ifdef REG_DEREG
321  cout << o << " " << s << " " << (unsigned long)t << "\n";
322 #endif
323  for (FreeCheckLink* fcl = next; fcl; fcl = fcl->next)
324  {
325  if (fcl->ClassStore==t)
326  {
327  if (last) last->next = fcl->next; else next = fcl->next;
328  if (s >= 0 && ((FCLRealArray*)fcl)->size != s)
329  {
330  cout << "\nArray sizes do not agree:\n";
331  cout << " " << o << " " << (unsigned long)t
332  << " " << ((FCLRealArray*)fcl)->size << " " << s << "\n";
334  cout << "\n";
335  }
336  delete fcl; return;
337  }
338  last = fcl;
339  }
340  cout << "\nRequest to delete non-existent real array:\n";
341  cout << " " << o << " " << (unsigned long)t << " " << s << "\n";
342  BadDelete++;
344  cout << "\n";
345 }
346 
347 void FreeCheck::DeRegisterI(void* t, char* o, int s)
348 {
349  FreeCheckLink* last = 0;
350 #ifdef REG_DEREG
351  cout << o << " " << s << " " << (unsigned long)t << "\n";
352 #endif
353  for (FreeCheckLink* fcl = next; fcl; fcl = fcl->next)
354  {
355  if (fcl->ClassStore==t)
356  {
357  if (last) last->next = fcl->next; else next = fcl->next;
358  if (s >= 0 && ((FCLIntArray*)fcl)->size != s)
359  {
360  cout << "\nArray sizes do not agree:\n";
361  cout << " " << o << " " << (unsigned long)t
362  << " " << ((FCLIntArray*)fcl)->size << " " << s << "\n";
364  cout << "\n";
365  }
366  delete fcl; return;
367  }
368  last = fcl;
369  }
370  cout << "\nRequest to delete non-existent int array:\n";
371  cout << " " << o << " " << (unsigned long)t << " " << s << "\n";
372  BadDelete++;
374  cout << "\n";
375 }
376 
377 void FreeCheck::Status()
378 {
379  if (next)
380  {
381  cout << "\nObjects of the following classes remain undeleted:\n";
382  for (FreeCheckLink* fcl = next; fcl; fcl = fcl->next) fcl->Report();
383  cout << "\n";
384  }
385  else cout << "\nNo objects remain undeleted\n\n";
386  if (BadDelete)
387  {
388  cout << "\nThere were " << BadDelete <<
389  " requests to delete non-existent items\n\n";
390  }
391 }
392 
393 #endif // end of DO_FREE_CHECK
394 
395 // derived exception bodies
396 
398 {
400  AddMessage("Logic error:- "); AddMessage(a_what);
401  if (a_what) Tracer::AddTrace();
402 }
403 
404 Runtime_error::Runtime_error(const char* a_what)
405  : BaseException()
406 {
408  AddMessage("Runtime error:- "); AddMessage(a_what);
409  if (a_what) Tracer::AddTrace();
410 }
411 
413 {
415  AddMessage("domain error\n"); AddMessage(a_what);
416  if (a_what) Tracer::AddTrace();
417 }
418 
420 {
422  AddMessage("invalid argument\n"); AddMessage(a_what);
423  if (a_what) Tracer::AddTrace();
424 }
425 
427 {
429  AddMessage("length error\n"); AddMessage(a_what);
430  if (a_what) Tracer::AddTrace();
431 }
432 
434 {
436  AddMessage("out of range\n"); AddMessage(a_what);
437  if (a_what) Tracer::AddTrace();
438 }
439 
440 //Bad_cast::Bad_cast(const char* a_what) : Logic_error()
441 //{
442 // Select = BaseException::Select;
443 // AddMessage("bad cast\n"); AddMessage(a_what);
444 // if (a_what) Tracer::AddTrace();
445 //}
446 
447 //Bad_typeid::Bad_typeid(const char* a_what) : Logic_error()
448 //{
449 // Select = BaseException::Select;
450 // AddMessage("bad type id.\n"); AddMessage(a_what);
451 // if (a_what) Tracer::AddTrace();
452 //}
453 
455 {
457  AddMessage("range error\n"); AddMessage(a_what);
458  if (a_what) Tracer::AddTrace();
459 }
460 
462 {
464  AddMessage("overflow error\n"); AddMessage(a_what);
465  if (a_what) Tracer::AddTrace();
466 }
467 
468 Bad_alloc::Bad_alloc(const char* a_what) : BaseException()
469 {
471  AddMessage("bad allocation\n"); AddMessage(a_what);
472  if (a_what) Tracer::AddTrace();
473 }
474 
475 
476 
477 
478 unsigned long Logic_error::Select;
479 unsigned long Runtime_error::Select;
480 unsigned long Domain_error::Select;
481 unsigned long Invalid_argument::Select;
482 unsigned long Length_error::Select;
483 unsigned long Out_of_range::Select;
484 //unsigned long Bad_cast::Select;
485 //unsigned long Bad_typeid::Select;
486 unsigned long Range_error::Select;
487 unsigned long Overflow_error::Select;
488 unsigned long Bad_alloc::Select;
489 
490 #ifdef use_namespace
491 }
492 #endif
493 
494 
496 
Janitor()
Definition: myexcept.h:220
Tracer * previous
Definition: myexcept.h:69
static void AddMessage(const char *a_what)
Definition: myexcept.cpp:73
static unsigned long Select
Definition: myexcept.h:381
static unsigned long Select
Definition: myexcept.h:360
void Terminate()
Definition: myexcept.cpp:226
virtual ~Janitor()
Definition: myexcept.h:221
static unsigned long Select
Definition: myexcept.h:430
Invalid_argument(const char *a_what=0)
Definition: myexcept.cpp:419
Out_of_range(const char *a_what=0)
Definition: myexcept.cpp:433
Domain_error(const char *a_what=0)
Definition: myexcept.cpp:412
static unsigned long Select
Definition: myexcept.h:374
Bad_alloc(const char *a_what=0)
Definition: myexcept.cpp:468
static unsigned long Select
Definition: myexcept.h:395
static unsigned long Select
Definition: myexcept.h:367
static void AddTrace()
Definition: myexcept.cpp:116
static unsigned long Select
Definition: myexcept.h:416
static unsigned long Select
Definition: myexcept.h:423
static Tracer * last
Definition: myexcept.h:76
Runtime_error(const char *a_what=0)
Definition: myexcept.cpp:404
Overflow_error(const char *a_what=0)
Definition: myexcept.cpp:461
Range_error(const char *a_what=0)
Definition: myexcept.cpp:454
#define Throw(E)
Definition: myexcept.h:191
static void PrintTrace()
Definition: myexcept.cpp:109
static int SoFar
Definition: myexcept.h:85
static const char * what()
Definition: myexcept.h:93
static int LastOne
Definition: myexcept.h:86
static void AddInt(int value)
Definition: myexcept.cpp:88
byte size
Definition: kni_wrapper.cpp:35
static unsigned long Select
Definition: myexcept.h:91
Logic_error(const char *a_what=0)
Definition: myexcept.cpp:397
BaseException(const char *a_what=0)
Definition: myexcept.cpp:55
static char * what_error
Definition: myexcept.h:84
static unsigned long Select
Definition: myexcept.h:388
Length_error(const char *a_what=0)
Definition: myexcept.cpp:426


kni
Author(s): Martin Günther
autogenerated on Fri Jan 3 2020 04:01:16