source: ntrip/trunk/BNC/newmat/myexcept.cpp@ 11076

Last change on this file since 11076 was 11050, checked in by stuerze, 4 weeks ago

minor changes: clean message buffer

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