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

Last change on this file since 10801 was 10791, checked in by mervart, 2 months ago

BNC Multifrequency and PPPAR Client (initial version)

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