⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 myexcept.cpp

📁 矩阵计算库
💻 CPP
字号:
//$$except.cpp                        Exception handler

// Copyright (C) 1993,4: R B Davies


#define WANT_STREAM                  // include.h will get stream fns


#include "include.h"                 // include standard files
#include "boolean.h"


#include "myexcept.h"                  // for exception handling

//#define REG_DEREG                    // for print out uses of new/delete
//#define CLEAN_LIST                   // to print entries being added to
                                       // or deleted from cleanup list

#ifdef SimulateExceptions

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(); }

#endif                               // end of simulate exceptions


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);
   }
}


#ifdef SimulateExceptions


Janitor::Janitor()
{
   if (do_not_link)
//   if (do_not_link || !JumpBase::jl)      // second term is for global
                                          // declarations when the JumpItem
                                          // list might be empty
   {
      do_not_link = FALSE; NextJanitor = 0; OnStack = FALSE;
#ifdef CLEAN_LIST
      cout << "Not added to clean-list " << (unsigned long)this << "\n";
#endif
   }
   else
   {
      OnStack = TRUE;
#ifdef CLEAN_LIST
      cout << "Add to       clean-list " << (unsigned long)this << "\n";
#endif
      NextJanitor = JumpBase::jl->janitor; JumpBase::jl->janitor=this;
   }
}

Janitor::~Janitor()
{
   // expect the item to be deleted to be first on list
   // but must be prepared to search list
   if (OnStack)
   {
#ifdef CLEAN_LIST
      cout << "Delete from  clean-list " << (unsigned long)this << "\n";
#endif
      Janitor* lastjan = JumpBase::jl->janitor;
      if (this == lastjan) JumpBase::jl->janitor = NextJanitor;
      else
      {
	 for (Janitor* jan = lastjan->NextJanitor; jan;
	    jan = lastjan->NextJanitor)
	 {
	    if (jan==this)
	       { lastjan->NextJanitor = jan->NextJanitor; return; }
	    lastjan=jan;
	 }

         cout << "\nCannot resolve memory linked list\n";
         cout << "See notes in except.cpp for details\n";
	 Throw(Exception(-1));
/*
This message occurs when a call to ~Janitor() occurs, apparently without
a corresponding call to Janitor(). This could happen if my way of
deciding whether a constructor is being called by new fails. It can also
happen if you have a class derived from Janitor which does not include a
copy constructor [ eg X(const &X) ]. Possibly also if delete is applied
an object on the stack (ie not called by new). Otherwise, it is a bug in
Newmat or your compiler. If you don't #define TEMPS_DESTROYED_QUICKLY
you will get this error with Microsoft C 7.0. There are probably
situations where you will get this when you do define
TEMPS_DESTROYED_QUICKLY. This is a bug in MSC. Beware of "operator"
statements for defining conversions; particularly for converting from a
Base class to a Derived class. 

You may get away with simply deleting this error message and Throw statement
if you can't find a better way of overcoming the problem. In any case please
tell me if you get this error message, particularly for compilers apart from
Microsoft C.
*/
      }
   }
}

JumpItem* JumpBase::jl;              // will be set to zero
long JumpBase::type;
jmp_buf JumpBase::env;
Boolean Janitor::do_not_link;        // will be set to FALSE


// static JumpItem JI;                  // need JumpItem at head of list



int JanitorInitializer::ref_count;

JanitorInitializer::JanitorInitializer()
{
   if (ref_count++ == 0)
   {
      new JumpItem;                 // need JumpItem at head of list
   }
}

#endif                            // end of SimulateExceptions

Tracer* Exception::last;             // will be set to zero


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;
int FreeCheck::BadDelete;

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); }
#ifdef REG_DEREG
   cout << "Registering   " << name << "   " << (unsigned long)t << "\n";
#endif
}

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); }
#ifdef REG_DEREG
   cout << o << "   " << s << "   " << (unsigned long)t << "\n";
#endif
}

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); }
#ifdef REG_DEREG
   cout << o << "   " << s << "   " << (unsigned long)t << "\n";
#endif
}

void FreeCheck::DeRegister(void* t, char* name)
{
   FreeCheckLink* last = 0;
#ifdef REG_DEREG
   cout << "Deregistering " << name << "   " << (unsigned long)t << "\n";
#endif
   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";
   BadDelete++;
   Exception::PrintTrace(TRUE);
   cout << "\n";
}

void FreeCheck::DeRegisterR(void* t, char* o, int s)
{
   FreeCheckLink* last = 0;
#ifdef REG_DEREG
   cout << o << "   " << s << "   " << (unsigned long)t << "\n";
#endif
   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";
   BadDelete++;
   Exception::PrintTrace(TRUE);
   cout << "\n";
}

void FreeCheck::DeRegisterI(void* t, char* o, int s)
{
   FreeCheckLink* last = 0;
#ifdef REG_DEREG
   cout << o << "   " << s << "   " << (unsigned long)t << "\n";
#endif
   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";
   BadDelete++;
   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\n";
   if (BadDelete)
   {
      cout << "\nThere were " << BadDelete << 
         " requests to delete non-existent items\n\n";
   }
}

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -