Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/lib/newmat/myexcept.cpp @ 4613

Last change on this file since 4613 was 4565, checked in by patrick, 19 years ago

orxonox/trunk: added the newmat library to the project. needs some translation in directory, temp under util/newmat. is needed by the collision detection engine to perform lin alg operations such as eigenvector decomposition. perhaps we will make our own library to do that later.

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