home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume34
/
newmat06
/
part06
/
except.cxx
< prev
next >
Wrap
C/C++ Source or Header
|
1992-12-06
|
6KB
|
218 lines
//$$except.cxx Exception handler
#define WANT_STREAM // include.h will get stream fns
#include "include.h" // include standard files
#include "boolean.h"
#include "except.h" // for exception handling
void Throw()
{
for (Janitor* jan = JumpBase::jl->janitor; jan; jan = jan->NextJanitor)
jan->CleanUp();
JumpBase::jl = JumpBase::jl->ji;
if ( ! JumpBase::jl ) Terminate();
Exception::last = JumpBase::jl->trace;
longjmp(JumpBase::jl->env, 1);
}
void Throw(const Exception& exc) { JumpBase::type = exc.type(); Throw(); }
void Exception::PrintTrace(Boolean)
{
cout << "\n";
{
for (Tracer* et = last; et; et=et->previous)
cout << " * " << et->entry << "\n";
}
}
Exception::Exception(int action)
{
if (action)
{
cout << "\nAn exception has occurred: call trace follows.";
PrintTrace();
if (action < 0) exit(1);
}
}
Janitor::Janitor()
{
if (do_not_link) { do_not_link = FALSE; NextJanitor = 0; OnStack = FALSE; }
else
{
OnStack = TRUE;
NextJanitor = JumpBase::jl->janitor; JumpBase::jl->janitor=this;
}
}
Janitor::~Janitor() { if (OnStack) JumpBase::jl->janitor = NextJanitor; }
JumpItem* JumpBase::jl = 0;
long JumpBase::type;
Tracer* Exception::last = 0;
Boolean Janitor::do_not_link = FALSE;
static JumpItem JI; // need JumpItem at head of list
void Terminate()
{
cout << "\nThere has been an exception with no handler - exiting\n";
exit(1);
}
#ifdef DO_FREE_CHECK
// Routines for tracing whether new and delete calls are balanced
FreeCheckLink::FreeCheckLink() : next(FreeCheck::next)
{ FreeCheck::next = this; }
FCLClass::FCLClass(void* t, char* name) : ClassName(name) { ClassStore=t; }
FCLRealArray::FCLRealArray(void* t, char* o, int s)
: Operation(o), size(s) { ClassStore=t; }
FCLIntArray::FCLIntArray(void* t, char* o, int s)
: Operation(o), size(s) { ClassStore=t; }
FreeCheckLink* FreeCheck::next = 0;
void FCLClass::Report()
{ cout << " " << ClassName << " " << (unsigned long)ClassStore << "\n"; }
void FCLRealArray::Report()
{
cout << " " << Operation << " " << (unsigned long)ClassStore <<
" " << size << "\n";
}
void FCLIntArray::Report()
{
cout << " " << Operation << " " << (unsigned long)ClassStore <<
" " << size << "\n";
}
void FreeCheck::Register(void* t, char* name)
{
FCLClass* f = new FCLClass(t,name);
if (!f) { cout << "Out of memory in FreeCheck\n"; exit(1); }
// cout << "Registering " << name << " " << (unsigned long)t << "\n";
}
void FreeCheck::RegisterR(void* t, char* o, int s)
{
FCLRealArray* f = new FCLRealArray(t,o,s);
if (!f) { cout << "Out of memory in FreeCheck\n"; exit(1); }
// cout << o << " " << s << " " << (unsigned long)t << "\n";
}
void FreeCheck::RegisterI(void* t, char* o, int s)
{
FCLIntArray* f = new FCLIntArray(t,o,s);
if (!f) { cout << "Out of memory in FreeCheck\n"; exit(1); }
// cout << o << " " << s << " " << (unsigned long)t << "\n";
}
void FreeCheck::DeRegister(void* t, char* name)
{
FreeCheckLink* last = 0;
// cout << "Deregistering " << name << " " << (unsigned long)t << "\n";
for (FreeCheckLink* fcl = next; fcl; fcl = fcl->next)
{
if (fcl->ClassStore==t)
{
if (last) last->next = fcl->next; else next = fcl->next;
delete fcl; return;
}
last = fcl;
}
cout << "\nRequest to delete non-existent object of class and location:\n";
cout << " " << name << " " << (unsigned long)t << "\n";
Exception::PrintTrace(TRUE);
cout << "\n";
}
void FreeCheck::DeRegisterR(void* t, char* o, int s)
{
FreeCheckLink* last = 0;
// cout << o << " " << s << " " << (unsigned long)t << "\n";
for (FreeCheckLink* fcl = next; fcl; fcl = fcl->next)
{
if (fcl->ClassStore==t)
{
if (last) last->next = fcl->next; else next = fcl->next;
if (((FCLRealArray*)fcl)->size != s)
{
cout << "\nArray sizes don't agree:\n";
cout << " " << o << " " << (unsigned long)t
<< " " << s << "\n";
Exception::PrintTrace(TRUE);
cout << "\n";
}
delete fcl; return;
}
last = fcl;
}
cout << "\nRequest to delete non-existent real array:\n";
cout << " " << o << " " << (unsigned long)t << " " << s << "\n";
Exception::PrintTrace(TRUE);
cout << "\n";
}
void FreeCheck::DeRegisterI(void* t, char* o, int s)
{
FreeCheckLink* last = 0;
// cout << o << " " << s << " " << (unsigned long)t << "\n";
for (FreeCheckLink* fcl = next; fcl; fcl = fcl->next)
{
if (fcl->ClassStore==t)
{
if (last) last->next = fcl->next; else next = fcl->next;
if (((FCLIntArray*)fcl)->size != s)
{
cout << "\nArray sizes don't agree:\n";
cout << " " << o << " " << (unsigned long)t
<< " " << s << "\n";
Exception::PrintTrace(TRUE);
cout << "\n";
}
delete fcl; return;
}
last = fcl;
}
cout << "\nRequest to delete non-existent int array:\n";
cout << " " << o << " " << (unsigned long)t << " " << s << "\n";
Exception::PrintTrace(TRUE);
cout << "\n";
}
void FreeCheck::Status()
{
if (next)
{
cout << "\nObjects of the following classes remain undeleted:\n";
for (FreeCheckLink* fcl = next; fcl; fcl = fcl->next) fcl->Report();
cout << "\n";
}
else cout << "\nNo objects remain undeleted\n";
}
#endif