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