Initial import of the CDE 2.1.30 sources from the Open Group.
This commit is contained in:
92
cde/programs/dtinfo/DtMmdb/dti_excs/Destructable.C
Normal file
92
cde/programs/dtinfo/DtMmdb/dti_excs/Destructable.C
Normal file
@@ -0,0 +1,92 @@
|
||||
// $XConsortium: Destructable.C /main/8 1996/10/04 12:48:45 cde-hal $
|
||||
#ifndef NATIVE_EXCEPTIONS
|
||||
#include "Exceptions.hh"
|
||||
|
||||
|
||||
void *Destructable::g_stack_start;
|
||||
unsigned short Destructable::g_size;
|
||||
|
||||
#ifdef C_API
|
||||
NEW_AND_DELETE_BODIES_SIMPLE(Destructable)
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef NOPE
|
||||
struct Init
|
||||
{
|
||||
Init() {}
|
||||
};
|
||||
|
||||
static Init I;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// in_stack - return true if ptr is in stack memory
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
int
|
||||
Destructable::in_stack()
|
||||
{
|
||||
char stack_end;
|
||||
PRINTF (("In_stack : %p -- %p | %p ",
|
||||
g_stack_start, &stack_end, this));
|
||||
|
||||
if (((void *) this > &stack_end && (void *) this < g_stack_start) ||
|
||||
((void *) this < &stack_end && (void *) this > g_stack_start))
|
||||
{
|
||||
PRINTF (("(stack)\n"));
|
||||
return (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF (("(heap)\n"));
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// in_stack_set_size - return 1 if in the stack, set size as well
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
int
|
||||
Destructable::in_stack_set_size()
|
||||
{
|
||||
char stack_end;
|
||||
PRINTF (("In_stack_size : %p -- %p | %p ",
|
||||
g_stack_start, &stack_end, this));
|
||||
|
||||
// Handle stack grows down case.
|
||||
if ((void *) this > (void *) &stack_end &&
|
||||
(void *) this < (void *) g_stack_start)
|
||||
{
|
||||
PRINTF (("(stack)\n"));
|
||||
// Size unknown, also used to indicate stack grows down.
|
||||
Destructable::g_size = 0;
|
||||
return (1);
|
||||
}
|
||||
// Handle stack grows up case.
|
||||
else if ((void *) this > (void *) g_stack_start &&
|
||||
(void *) this < (void *) &stack_end)
|
||||
{
|
||||
// stack_end is just past this, so size is space between them.
|
||||
Destructable::g_size = (unsigned long) &stack_end - (unsigned long) this;
|
||||
#ifdef foobar
|
||||
g_size -=
|
||||
#endif
|
||||
PRINTF (("(stack)\n"));
|
||||
PRINTF ((" obj start = %p, end = %p, size = %d\n",
|
||||
this, &stack_end, g_size));
|
||||
|
||||
return (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF (("(heap)\n"));
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* NATIVE_EXCEPTIONS */
|
||||
44
cde/programs/dtinfo/DtMmdb/dti_excs/Destructable.hh
Normal file
44
cde/programs/dtinfo/DtMmdb/dti_excs/Destructable.hh
Normal file
@@ -0,0 +1,44 @@
|
||||
// $XConsortium: Destructable.hh /main/3 1996/06/11 16:50:40 cde-hal $
|
||||
#ifndef _Exceptions_hh_active
|
||||
#error "Include this file by including Exceptions.hh"
|
||||
#endif
|
||||
|
||||
#ifdef C_API
|
||||
#include "new_delete_simple.h"
|
||||
#endif
|
||||
|
||||
class Destructable
|
||||
{
|
||||
#ifndef NATIVE_EXCEPTIONS
|
||||
public:
|
||||
Destructable();
|
||||
// Copy and assignment constructors necessary to maintain proper
|
||||
// f_in_stack state variable.
|
||||
Destructable (const Destructable &);
|
||||
Destructable &operator = (const Destructable &);
|
||||
virtual ~Destructable();
|
||||
|
||||
int in_stack();
|
||||
int in_stack_set_size();
|
||||
|
||||
#ifdef C_API
|
||||
NEW_AND_DELETE_SIGNATURES(Destructable);
|
||||
#endif
|
||||
|
||||
private:
|
||||
friend class Jump_Environment;
|
||||
friend class Exceptions;
|
||||
static int stack_grows_down()
|
||||
{ return (g_size == 0); }
|
||||
|
||||
// Need this special method since Cfront 2.1 doesn't allow direct
|
||||
// call to destructor from another class.
|
||||
void destruct();
|
||||
|
||||
static void *g_stack_start;
|
||||
// We keep track of the size when the stack grows up.
|
||||
// This is copied over to the unwind stack for stack-based objects.
|
||||
static unsigned short g_size;
|
||||
|
||||
#endif
|
||||
};
|
||||
91
cde/programs/dtinfo/DtMmdb/dti_excs/Destructable_il.hh
Normal file
91
cde/programs/dtinfo/DtMmdb/dti_excs/Destructable_il.hh
Normal file
@@ -0,0 +1,91 @@
|
||||
// $TOG: Destructable_il.hh /main/9 1998/04/20 10:06:23 mgreess $
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// class constructor
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
inline
|
||||
Destructable::Destructable()
|
||||
{
|
||||
// Make sure the application has initialized this library.
|
||||
#ifdef DEBUG
|
||||
Exceptions::check_initialized();
|
||||
#endif
|
||||
|
||||
if (in_stack_set_size())
|
||||
Jump_Environment::register_object (this);
|
||||
PRINTF ((" Constructed obj @ %p\n", this));
|
||||
}
|
||||
|
||||
|
||||
// NOTE: Both the copy and assignment constructors below init
|
||||
// f_constructed to 0, which is going to be bogus if the derived
|
||||
// class checks this value. This is a problem because we don't
|
||||
// know if the derived class uses the default copy constructor or
|
||||
// not. If it does we want f_constructed to be set to 1, otherwise
|
||||
// we want it to be set to 0 until its methods complete.
|
||||
// Ugh!
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// copy constructor
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
inline
|
||||
Destructable::Destructable (const Destructable &)
|
||||
{
|
||||
if (in_stack_set_size())
|
||||
Jump_Environment::register_object (this);
|
||||
PRINTF ((" Copy ctor @ %p\n", this));
|
||||
}
|
||||
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// assignment operator
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
inline Destructable &
|
||||
Destructable::operator = (const Destructable &)
|
||||
{
|
||||
// Assignment operator does nothing to preserve state of original
|
||||
// creation of this object. State information is permanently
|
||||
// associated with a Destructable object and cannot be assigned to.
|
||||
PRINTF (("Assign op @ %p\n", this));
|
||||
return (*this);
|
||||
}
|
||||
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// class destructor
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
// There is currently no checking here for objects that have not
|
||||
// been constructed. It is possible for this to be called for such
|
||||
// objects if an exception is thrown in a constructor. See test18.C.
|
||||
|
||||
inline
|
||||
Destructable::~Destructable()
|
||||
{
|
||||
if (in_stack())
|
||||
Jump_Environment::unregister_object (this);
|
||||
}
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// destruct function
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
// This code relies on the fact that in cfront 2.1 this qualified
|
||||
// call to the destructor will actually call the virtual destructor.
|
||||
|
||||
#if (!defined(hpux)) && (!defined(__uxp__)) && (CC_VERSION < 30)
|
||||
inline void
|
||||
Destructable::destruct()
|
||||
{
|
||||
#if defined(linux)
|
||||
delete this;
|
||||
#else
|
||||
// Have to call this here since some compilers don't allow
|
||||
// qualified calls through object pointer.
|
||||
Destructable::~Destructable();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
235
cde/programs/dtinfo/DtMmdb/dti_excs/Exception.C
Normal file
235
cde/programs/dtinfo/DtMmdb/dti_excs/Exception.C
Normal file
@@ -0,0 +1,235 @@
|
||||
// $XConsortium: Exception.C /main/4 1996/10/04 09:40:25 drk $
|
||||
#ifndef NATIVE_EXCEPTIONS
|
||||
#include "Exceptions.hh"
|
||||
#include <memory.h>
|
||||
|
||||
Exception *Exception::g_current_exception;
|
||||
|
||||
#ifdef C_API
|
||||
char* Exception::g_temp_space = 0;
|
||||
char *Exception::g_next_avail = 0;
|
||||
#else
|
||||
char Exception::g_temp_space[G_TEMP_SPACE_SIZE];
|
||||
char *Exception::g_next_avail = Exception::g_temp_space;
|
||||
#endif
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// class constructor
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
Exception::Exception()
|
||||
: f_line(0), f_thrown_as_pointer(1), f_thrown(0), f_temporary(0)
|
||||
{
|
||||
PRINTF (("Constructed Exception obj @ %p\n", this));
|
||||
}
|
||||
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// operator delete
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
Exception::operator delete (void *place)
|
||||
{
|
||||
// Move pointer back if it's in our temp space, else just free it.
|
||||
if (place >= g_temp_space && place < g_temp_space + G_TEMP_SPACE_SIZE)
|
||||
{
|
||||
g_next_avail = (char *) place;
|
||||
PRINTF (("De-alloc EXC @ %p\n", place));
|
||||
}
|
||||
else
|
||||
{
|
||||
free ((char *) place);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// operator new
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
// int arg is only used for type matching to insure that our version
|
||||
// of new gets called to make temporaries.
|
||||
|
||||
void *
|
||||
Exception::operator new (size_t size, int)
|
||||
{
|
||||
if (g_next_avail + size <= g_temp_space + G_TEMP_SPACE_SIZE)
|
||||
{
|
||||
void *p = g_next_avail;
|
||||
g_next_avail += size;
|
||||
PRINTF (("Allocate EXC @ %p, size = %ld\n", p, (long)size));
|
||||
return (p);
|
||||
}
|
||||
else
|
||||
{
|
||||
Exceptions::error (Exceptions::f_msg_out_of_exception_memory,
|
||||
Exceptions::INTERNAL_ERROR);
|
||||
terminate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// throw_it
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
// According to ARM, 15.2c temporary object thrown is of the static
|
||||
// type of the operand to throw, so this method must be non-virtual.
|
||||
// A non-virtual version of this function is created with macros in
|
||||
// each subclass of the Exception object. See Exception.hh.
|
||||
|
||||
void
|
||||
Exception::throw_it (unsigned int line, const char *file, int dbg)
|
||||
{
|
||||
// NOTE: This is the only place we can detect a throw of a pointer
|
||||
// to a stack based object.
|
||||
|
||||
Exception *temp;
|
||||
PRINTF (("Preparing to throw Exception object at %p:\n", this));
|
||||
|
||||
// Only make a temporary if the exception object is on the stack.
|
||||
if (in_stack())
|
||||
{
|
||||
PRINTF ((" Exception is on the stack - copying it\n"));
|
||||
// Use the special new operator which allocates the exception
|
||||
// in reserved storage if there's no memory available.
|
||||
temp = new (0) Exception (*this);
|
||||
// We created it, so we should delete it.
|
||||
temp->f_temporary = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF ((" Exception is on the heap\n"));
|
||||
temp = this;
|
||||
}
|
||||
|
||||
temp->do_throw (line, file, dbg);
|
||||
}
|
||||
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// throw - throw the current exception
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
Exception::do_throw (unsigned int line, const char *file, int debugging)
|
||||
{
|
||||
#ifdef EXC_DEBUG
|
||||
if (f_line == 0)
|
||||
{
|
||||
PRINTF (("========== Throwing exception ==========\n"));
|
||||
}
|
||||
else // must be a rethrow
|
||||
{
|
||||
PRINTF (("========== Re-throwing exception ==========\n"));
|
||||
}
|
||||
#endif
|
||||
|
||||
// Save line and file if we don't already have it.
|
||||
if (f_line == 0)
|
||||
{
|
||||
f_line = line;
|
||||
f_file = file;
|
||||
}
|
||||
|
||||
f_thrown = 1;
|
||||
Jump_Environment::unwind_and_jump (this, debugging);
|
||||
}
|
||||
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// current_exception - return the current exception
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
Exception &
|
||||
Exception::current_exception()
|
||||
{
|
||||
if (g_current_exception == NULL)
|
||||
{
|
||||
Exceptions::error (Exceptions::f_msg_no_current_exception,
|
||||
Exceptions::APPLICATION_ERROR);
|
||||
terminate();
|
||||
}
|
||||
|
||||
return (*g_current_exception);
|
||||
}
|
||||
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// (un)make_current - (un)make this exception the current one
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
Exception::unmake_current()
|
||||
{
|
||||
PRINTF (("Current Exc POP %p <-- %p\n",
|
||||
g_current_exception, f_previous_exception));
|
||||
if (this != g_current_exception)
|
||||
{
|
||||
Exceptions::error ("Popped exception is the current one!",
|
||||
Exceptions::INTERNAL_ERROR);
|
||||
terminate();
|
||||
}
|
||||
|
||||
// Called when a catch clause is exited.
|
||||
g_current_exception = f_previous_exception;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Exception::make_current()
|
||||
{
|
||||
PRINTF (("Current Exc PUSH --> %p\n", this));
|
||||
f_previous_exception = g_current_exception;
|
||||
g_current_exception = this;
|
||||
}
|
||||
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// relocate - move this exception to the current top of stack
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
Exception::relocate (Exception **exception, int length)
|
||||
{
|
||||
PRINTF (("Moving %p --> %p (%d bytes)\n",
|
||||
*exception, g_next_avail, length));
|
||||
// Slide the specified exception down to fill the hole below it.
|
||||
if (g_next_avail >= (char *) *exception)
|
||||
abort();
|
||||
memcpy (g_next_avail, *exception, length);
|
||||
*exception = (Exception *) g_next_avail;
|
||||
g_next_avail = ((char *) *exception) + length;
|
||||
}
|
||||
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// is - return true this class is of type TYPE
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
int
|
||||
Exception::is (const char *type, const char *this_class)
|
||||
{
|
||||
PRINTF (("Type specified is <%s>\n", type));
|
||||
|
||||
while (isalnum (*type) && isalnum (*this_class) &&
|
||||
*type++ == *this_class++);
|
||||
if (isalnum (*type) || isalnum (*this_class))
|
||||
return (0);
|
||||
|
||||
// Check for pointer types
|
||||
while (isspace (*type))
|
||||
{
|
||||
type++;
|
||||
}
|
||||
PRINTF ((" var part is <%s>\n", type));
|
||||
|
||||
// See if one's a pointer and the other isn't.
|
||||
if (*type == '*' && !f_thrown_as_pointer ||
|
||||
*type != '*' && f_thrown_as_pointer)
|
||||
return (0);
|
||||
// Otherwise they are either both pointers or both objects/references.
|
||||
return (1);
|
||||
}
|
||||
#endif /* NATIVE_EXCEPTIONS */
|
||||
205
cde/programs/dtinfo/DtMmdb/dti_excs/Exception.hh
Normal file
205
cde/programs/dtinfo/DtMmdb/dti_excs/Exception.hh
Normal file
@@ -0,0 +1,205 @@
|
||||
// $TOG: Exception.hh /main/11 1998/04/20 09:55:15 mgreess $
|
||||
#include <ctype.h>
|
||||
|
||||
#define G_TEMP_SPACE_SIZE 1024
|
||||
|
||||
#if defined(linux)
|
||||
#define CASTEXCEPT (Exception*)
|
||||
#else
|
||||
#define CASTEXCEPT
|
||||
#endif
|
||||
|
||||
class Exception : public Destructable
|
||||
{
|
||||
public:
|
||||
#ifdef NATIVE_EXCEPTIONS
|
||||
|
||||
#if defined(hpux)
|
||||
Exception() { }
|
||||
#endif
|
||||
|
||||
#else
|
||||
Exception();
|
||||
|
||||
#if defined(linux) && defined(EXC_DEBUG)
|
||||
~Exception()
|
||||
{
|
||||
PRINTF (("Destroying Exception @ %p\n", this));
|
||||
}
|
||||
#elif defined(EXC_DEBUG)
|
||||
~Exception()
|
||||
{
|
||||
PRINTF (("Destroying Exception @ %p\n", this));
|
||||
}
|
||||
#endif
|
||||
|
||||
// For printing debugging info. Can be overloaded by derived classes.
|
||||
virtual void print_exception()
|
||||
{ }
|
||||
|
||||
virtual const char *class_name()
|
||||
{ return ("Exception"); }
|
||||
|
||||
Exception *prepare_to_throw();
|
||||
|
||||
// This operator invoked if this is thrown as an object/reference
|
||||
Exception *operator ->()
|
||||
{ if (!f_thrown) f_thrown_as_pointer = 0;
|
||||
return (this); }
|
||||
|
||||
operator Exception *()
|
||||
{ return (this); }
|
||||
|
||||
virtual int isa (const char *type)
|
||||
{ return (is (type, "Exception")); }
|
||||
|
||||
int is (const char *type, const char *this_class);
|
||||
|
||||
static Exception ¤t_exception();
|
||||
|
||||
const char *file()
|
||||
{ return (f_file); }
|
||||
unsigned short line()
|
||||
{ return (f_line); }
|
||||
|
||||
// Need to provide a plain operator new definition because we
|
||||
// have a definition of the other one below. (See the ARM.)
|
||||
|
||||
#ifndef USL
|
||||
static void *operator new (size_t size)
|
||||
{ return (::operator new (size)); }
|
||||
#endif
|
||||
|
||||
static void operator delete (void *place);
|
||||
|
||||
// For initial throw. Redefined by decendents.
|
||||
// Makes temporaries for stack based objects and calls do_throw.
|
||||
void throw_it (unsigned int line, const char *file, int debugging);
|
||||
|
||||
// Actual throw code. Also used for rethrows.
|
||||
void do_throw (unsigned int line = 0,
|
||||
const char *file = "(unknown)",
|
||||
int debugging = 0);
|
||||
|
||||
// Length is only valid for exceptions at the top of the stack!
|
||||
int length() { return (g_next_avail - (char *) this); }
|
||||
void unmake_current();
|
||||
void make_current();
|
||||
static void relocate (Exception **exception, int length);
|
||||
|
||||
protected:
|
||||
friend class Jump_Environment;
|
||||
friend class Exceptions;
|
||||
|
||||
#if defined(hpux)||defined(__uxp__)
|
||||
#define MakeOperatorNewPublic
|
||||
#endif
|
||||
|
||||
#ifdef MakeOperatorNewPublic
|
||||
// A problem with the HP-UX 3.65 compiler requires us to make this public.
|
||||
// And, since we gen the Templates.nd.c file on a non-HPUX platform, we need
|
||||
// a second way to trigger the change.
|
||||
public:
|
||||
#endif
|
||||
static void *operator new (size_t size, int);
|
||||
#ifdef MakeOperatorNewPublic
|
||||
protected:
|
||||
#endif
|
||||
|
||||
// f_thrown flag is a safty feature to make sure that the f_throw_as_pointer
|
||||
// flag can't be reset accidently by the user calling operator ->
|
||||
|
||||
#ifdef PURIFY
|
||||
unsigned char f_thrown;
|
||||
unsigned char f_thrown_as_pointer;
|
||||
unsigned char f_temporary;
|
||||
#else
|
||||
unsigned char f_thrown : 1;
|
||||
unsigned char f_thrown_as_pointer : 1;
|
||||
unsigned char f_temporary : 1;
|
||||
#endif
|
||||
|
||||
private:
|
||||
// Line and file where exception was originally thrown from.
|
||||
const char *f_file;
|
||||
unsigned short f_line;
|
||||
Exception *f_previous_exception;
|
||||
|
||||
static Exception *g_current_exception;
|
||||
|
||||
#ifdef C_API
|
||||
static char *g_temp_space;
|
||||
#else
|
||||
static char g_temp_space[G_TEMP_SPACE_SIZE];
|
||||
#endif
|
||||
|
||||
static char *g_next_avail;
|
||||
|
||||
#ifdef C_API
|
||||
friend void initialize_exception();
|
||||
friend void quit_exception();
|
||||
#endif
|
||||
|
||||
#endif /* NATIVE_EXCEPTIONS */
|
||||
};
|
||||
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// DECLARE_EXCEPTION - macros for derived classes
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef NATIVE_EXCEPTIONS
|
||||
// NOTE: class_name, is, and isa should be renamed to _exc_...
|
||||
|
||||
#define _DECL_START(NAME) \
|
||||
const char *class_name() \
|
||||
{ return (STRINGIFY(NAME)); } \
|
||||
void throw_it (unsigned int line, const char *file, int dbg) \
|
||||
{ Exception *temp; \
|
||||
if (in_stack()) { \
|
||||
temp = new (0) NAME (*this); \
|
||||
(Exception *) (((NAME *)temp)->f_temporary = 1); \
|
||||
} else \
|
||||
temp = this; \
|
||||
temp->do_throw (line, file, dbg); } \
|
||||
NAME *operator ->() { if (!f_thrown) f_thrown_as_pointer = 0; \
|
||||
return (this); } \
|
||||
operator NAME *() { return (this); } \
|
||||
int isa (const char *type) \
|
||||
{ return (is (type, STRINGIFY(NAME)) ||
|
||||
|
||||
#define _DECL_END \
|
||||
); } \
|
||||
|
||||
// MUST be the first thing in a subclass or protections get screwed up.
|
||||
|
||||
#define DECLARE_EXCEPTION DECLARE_EXCEPTION1
|
||||
|
||||
#define DECLARE_EXCEPTION1(NAME,SUPER1) \
|
||||
_DECL_START (NAME) \
|
||||
SUPER1::isa (type) \
|
||||
_DECL_END
|
||||
|
||||
#define DECLARE_EXCEPTION2(NAME,SUPER1,SUPER2) \
|
||||
_DECL_START (NAME) \
|
||||
SUPER1::isa (type) || \
|
||||
SUPER2::isa (type) \
|
||||
_DECL_END
|
||||
|
||||
#define DECLARE_EXCEPTION3(NAME,SUPER1,SUPER2,SUPER3) \
|
||||
_DECL_START (NAME) \
|
||||
SUPER1::isa (type) || \
|
||||
SUPER2::isa (type) || \
|
||||
SUPER3::isa (type) \
|
||||
_DECL_END
|
||||
|
||||
#else
|
||||
|
||||
#define DECLARE_EXCEPTION(NAME,SUPER1)
|
||||
#define DECLARE_EXCEPTION1(NAME,SUPER1)
|
||||
#define DECLARE_EXCEPTION2(NAME,SUPER1,SUPER2)
|
||||
#define DECLARE_EXCEPTION3(NAME,SUPER1,SUPER2)
|
||||
|
||||
#endif /* NATIVE_EXCEPTIONS */
|
||||
|
||||
// Users can define more if they need to...
|
||||
213
cde/programs/dtinfo/DtMmdb/dti_excs/Exceptions.C
Normal file
213
cde/programs/dtinfo/DtMmdb/dti_excs/Exceptions.C
Normal file
@@ -0,0 +1,213 @@
|
||||
// $XConsortium: Exceptions.cc /main/3 1996/06/11 16:51:03 cde-hal $
|
||||
#ifndef NATIVE_EXCEPTIONS
|
||||
#include "Exceptions.hh"
|
||||
//#include <new.h>
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef C_API
|
||||
char* Exceptions::f_msg_internal_error = 0;
|
||||
char* Exceptions::f_msg_application_error = 0;
|
||||
char* Exceptions::f_msg_throw_message = 0;
|
||||
char* Exceptions::f_msg_not_initialized = 0;
|
||||
char* Exceptions::f_msg_initialized_twice = 0;
|
||||
char* Exceptions::f_msg_not_caught = 0;
|
||||
char* Exceptions::f_msg_no_current_exception = 0;
|
||||
char* Exceptions::f_msg_throw_from_terminate = 0;
|
||||
char* Exceptions::f_msg_throw_from_error_handler = 0;
|
||||
char* Exceptions::f_msg_throw_from_destructor = 0;
|
||||
char* Exceptions::f_msg_throw_ptr_to_stack = 0;
|
||||
char* Exceptions::f_msg_out_of_exception_memory = 0;
|
||||
char* Exceptions::f_msg_out_of_obj_stack_memory = 0;
|
||||
char* Exceptions::f_msg_memory_already_freed = 0;
|
||||
#else
|
||||
char *Exceptions::f_msg_internal_error = "Internal exceptions error:";
|
||||
char *Exceptions::f_msg_application_error = "Application exceptions error:";
|
||||
char *Exceptions::f_msg_throw_message = "Application threw exception:";
|
||||
|
||||
char *Exceptions::f_msg_not_initialized =
|
||||
"Exceptions library not initialized with INIT_EXCEPTIONS().";
|
||||
|
||||
char *Exceptions::f_msg_initialized_twice =
|
||||
"Attept to call INIT_EXCEPTIONS() more than once.";
|
||||
|
||||
char *Exceptions::f_msg_not_caught =
|
||||
"Exception not caught.";
|
||||
|
||||
char *Exceptions::f_msg_no_current_exception =
|
||||
"There is no current exception (for catch or rethrow).";
|
||||
|
||||
char *Exceptions::f_msg_throw_from_terminate =
|
||||
"Exceptions may not be thrown from terminate.";
|
||||
|
||||
char *Exceptions::f_msg_throw_from_error_handler =
|
||||
"Exceptions may not be thrown from error handler.";
|
||||
|
||||
char *Exceptions::f_msg_throw_from_destructor =
|
||||
"Exited destructor with throw while handling an exception.";
|
||||
|
||||
char *Exceptions::f_msg_throw_ptr_to_stack =
|
||||
"Threw a pointer to an automatic (stack-based) exceptions object.";
|
||||
|
||||
char *Exceptions::f_msg_out_of_exception_memory =
|
||||
"Not enough memory to allocate an exception object.";
|
||||
|
||||
char *Exceptions::f_msg_out_of_obj_stack_memory =
|
||||
"Not enough memory to allocate object stack.";
|
||||
|
||||
char *Exceptions::f_msg_memory_already_freed =
|
||||
"Tried to alloc or realloc pool memory that was previously freed.";
|
||||
|
||||
#endif
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// initialize - initialize the exceptions library
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
Exceptions::initialize (void *ptr)
|
||||
{
|
||||
PRINTF (("Initializing exceptions library\n"));
|
||||
|
||||
if (Destructable::g_stack_start != NULL)
|
||||
{
|
||||
error (f_msg_initialized_twice, APPLICATION_ERROR);
|
||||
terminate();
|
||||
}
|
||||
else
|
||||
{
|
||||
// These two values MUST be initialized before the static
|
||||
// Jump_Environment below, or the its Destructable base class
|
||||
// constructor will fail because it won't think the library
|
||||
// is initialized or it may think the Jump Environment is on
|
||||
// the stack because f_stack_start is 0.
|
||||
Destructable::g_stack_start = ptr;
|
||||
|
||||
// The following is the global jump environment. According to ARM
|
||||
// (6.7) this isn't initialized until the first call to this function,
|
||||
// NOT at a global level before main() is called. This is important
|
||||
// because Jump_Environment is subclassed of Destructable, whose
|
||||
// constructor expects g_stack_start to be non-zero.
|
||||
static Jump_Environment __jump_env;
|
||||
|
||||
if (setjmp (__jump_env.f_env) != 0)
|
||||
{
|
||||
// Re-set base environment to allow for the creation of
|
||||
// Destructable objects in error handler and terminate
|
||||
// terminate function.
|
||||
Jump_Environment::g_jump_env_stack = &__jump_env;
|
||||
|
||||
error (f_msg_not_caught, APPLICATION_ERROR);
|
||||
terminate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Static variable declarations
|
||||
|
||||
Exceptions::error_handler_t Exceptions::g_error_handler;
|
||||
|
||||
// Error message declarations
|
||||
// The error messages are stored here because many appear in the
|
||||
// header files and we don't want to duplicate them in every app
|
||||
// that uses the header files.
|
||||
|
||||
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// set_error_handler
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
Exceptions::error_handler_t
|
||||
Exceptions::set_error_handler (error_handler_t error_handler)
|
||||
{
|
||||
error_handler_t previous = g_error_handler;
|
||||
g_error_handler = error_handler;
|
||||
return (previous);
|
||||
}
|
||||
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// error - print a useful error message
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
Exceptions::error (const char *message, error_type_t error_type)
|
||||
{
|
||||
static char buffer[3][100];
|
||||
static char *lines[3] = { buffer[0], buffer[1], buffer[2] };
|
||||
int count = 0;
|
||||
|
||||
if (error_type == INTERNAL_ERROR)
|
||||
strcpy (buffer[count++], f_msg_internal_error);
|
||||
else if (error_type == APPLICATION_ERROR)
|
||||
strcpy (buffer[count++], f_msg_application_error);
|
||||
else
|
||||
strcpy (buffer[count++], f_msg_throw_message);
|
||||
|
||||
// Don't use fprintf because it may try to allocate memory.
|
||||
if (Exception::g_current_exception != NULL)
|
||||
{
|
||||
sprintf (buffer[count++],
|
||||
" In exception thrown in file \"%s\", line %d,",
|
||||
Exception::g_current_exception->f_file,
|
||||
Exception::g_current_exception->f_line);
|
||||
}
|
||||
|
||||
if (message != NULL)
|
||||
sprintf (buffer[count++], " %s", message);
|
||||
|
||||
// Call user print function if set, otherwise just dump lines.
|
||||
if (g_error_handler != NULL)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Reset global variable to NULL before calling to prevent
|
||||
// the possibility of recursive calls.
|
||||
Exceptions::error_handler_t current = set_error_handler (NULL);
|
||||
(*current) ((const char**)lines, count);
|
||||
set_error_handler (current);
|
||||
}
|
||||
catch_any()
|
||||
{
|
||||
// Error handler will be NULL at this point.
|
||||
Exceptions::error (Exceptions::f_msg_throw_from_error_handler,
|
||||
Exceptions::APPLICATION_ERROR);
|
||||
terminate();
|
||||
|
||||
}
|
||||
end_try;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
fputs (buffer[i], stderr);
|
||||
fputc ('\n', stderr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// check_initialized - exit with error if not initialized
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
Exceptions::check_initialized()
|
||||
{
|
||||
void terminate();
|
||||
if (Destructable::g_stack_start == NULL)
|
||||
{
|
||||
// Can't call user defined error handler unless we're initialized.
|
||||
// Also can't do lazy initialization because we need the stack
|
||||
// pointer from the start of main, not here. From here is good
|
||||
// enough for terminating, however.
|
||||
INIT_EXCEPTIONS();
|
||||
error (f_msg_not_initialized, APPLICATION_ERROR);
|
||||
terminate();
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* NATIVE_EXCEPTIONS */
|
||||
188
cde/programs/dtinfo/DtMmdb/dti_excs/Exceptions.hh
Normal file
188
cde/programs/dtinfo/DtMmdb/dti_excs/Exceptions.hh
Normal file
@@ -0,0 +1,188 @@
|
||||
// $XConsortium: Exceptions.hh /main/4 1996/07/05 15:16:42 rws $
|
||||
#ifndef _Exceptions_hh
|
||||
#define _Exceptions_hh
|
||||
|
||||
#define _Exceptions_hh_active
|
||||
|
||||
#ifndef NATIVE_EXCEPTIONS
|
||||
|
||||
extern "C" {
|
||||
#include <setjmp.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <malloc.h>
|
||||
}
|
||||
|
||||
#ifdef EXC_DEBUG
|
||||
#define PRINTF(MSG) printf MSG
|
||||
#ifndef DEBUG
|
||||
#define DEBUG
|
||||
#endif
|
||||
#ifndef DEBUG_THROW
|
||||
#define DEBUG_THROW
|
||||
#endif
|
||||
#ifndef DEBUG_CATCH
|
||||
#define DEBUG_CATCH
|
||||
#endif
|
||||
#else
|
||||
#define PRINTF(MSG)
|
||||
#endif
|
||||
|
||||
#ifndef STRINGIFY
|
||||
#if !defined(__STDC__) && !defined(hpux)
|
||||
#define STRINGIFY(S) "S"
|
||||
#else
|
||||
#define STRINGIFY(S) #S
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* NATIVE_EXCEPTIONS */
|
||||
|
||||
#include "terminate.hh"
|
||||
#include "Destructable.hh"
|
||||
#include "Exception.hh"
|
||||
|
||||
#ifdef NATIVE_EXCEPTIONS
|
||||
|
||||
#define INIT_EXCEPTIONS()
|
||||
|
||||
#define throw(OBJ) throw OBJ
|
||||
#define rethrow throw
|
||||
|
||||
#define catch_any() catch(...)
|
||||
#define catch_noarg(OBJ) catch(OBJ)
|
||||
#define catch(TYPE,OBJ) catch(TYPE OBJ)
|
||||
|
||||
#define end_try
|
||||
|
||||
#else
|
||||
|
||||
// This macro, which should be the first thing in main, establishes a jump
|
||||
// environment for the context of the entire program.
|
||||
|
||||
#define INIT_EXCEPTIONS() \
|
||||
{ int __stack_start; Exceptions::initialize (&__stack_start); }
|
||||
|
||||
// TRY MACRO
|
||||
|
||||
#define try \
|
||||
{ \
|
||||
Jump_Environment __jump_env; \
|
||||
if (setjmp (__jump_env.f_env) == 0) {
|
||||
|
||||
|
||||
// THROW MACROS
|
||||
|
||||
#ifdef DEBUG_THROW
|
||||
#define DEBUG_THROW_FLAG 1
|
||||
#else
|
||||
#define DEBUG_THROW_FLAG 0
|
||||
#endif
|
||||
|
||||
// This works if OBJ is an object or a pointer since Exception objects
|
||||
// overload operator ->.
|
||||
#if !defined(hpux) && !defined(USL)
|
||||
#define throw(OBJ) \
|
||||
(OBJ)->throw_it (__LINE__, __FILE__, DEBUG_THROW_FLAG)
|
||||
#else
|
||||
#define throw(OBJ) \
|
||||
OBJ->throw_it (__LINE__, __FILE__, DEBUG_THROW_FLAG)
|
||||
#endif
|
||||
|
||||
#define rethrow \
|
||||
Exception::current_exception().do_throw (__LINE__, __FILE__)
|
||||
|
||||
// CATCH MACROS
|
||||
|
||||
#ifdef DEBUG_CATCH
|
||||
#define PRINT_CATCH \
|
||||
fprintf (stderr, "Application caught exception:\n"); \
|
||||
fprintf (stderr, " Thrown from file \"%s\", line %d\n", \
|
||||
Exception::current_exception().file(), \
|
||||
Exception::current_exception().line()); \
|
||||
fprintf (stderr, " Caught in file \"%s\", line %d.\n", \
|
||||
__FILE__, __LINE__);
|
||||
#else
|
||||
#define PRINT_CATCH
|
||||
#endif
|
||||
|
||||
#define catch_any() \
|
||||
} else if (1) { \
|
||||
PRINT_CATCH
|
||||
|
||||
#define catch_noarg(OBJ) \
|
||||
} else if (Exception::current_exception().isa (STRINGIFY(OBJ))) { \
|
||||
PRINT_CATCH
|
||||
|
||||
#define catch(TYPE,OBJ) \
|
||||
catch_noarg (TYPE) \
|
||||
TYPE OBJ = (TYPE) Exception::current_exception();
|
||||
|
||||
#define end_try \
|
||||
} else { \
|
||||
rethrow; \
|
||||
} \
|
||||
}
|
||||
|
||||
class Exceptions
|
||||
{
|
||||
public:
|
||||
typedef void (*error_handler_t) (const char *[], int);
|
||||
|
||||
static void initialize (void *ptr);
|
||||
|
||||
// Error handling stuff (message appear below).
|
||||
enum error_type_t { INTERNAL_ERROR, APPLICATION_ERROR, THROW_MESSAGE };
|
||||
static void error (const char *, error_type_t);
|
||||
static error_handler_t set_error_handler (error_handler_t);
|
||||
|
||||
private:
|
||||
friend class Destructable;
|
||||
friend class Jump_Environment;
|
||||
friend class Unwind_Stack;
|
||||
friend class Exception;
|
||||
friend void terminate();
|
||||
|
||||
static void check_initialized();
|
||||
|
||||
protected: // variables
|
||||
// function pointer to error message handler
|
||||
static error_handler_t g_error_handler;
|
||||
|
||||
// Error types
|
||||
static char *f_msg_internal_error;
|
||||
static char *f_msg_application_error;
|
||||
static char *f_msg_throw_message;
|
||||
|
||||
// Usage errors.
|
||||
static char *f_msg_not_initialized;
|
||||
static char *f_msg_initialized_twice;
|
||||
static char *f_msg_not_caught;
|
||||
static char *f_msg_no_current_exception;
|
||||
static char *f_msg_throw_from_terminate;
|
||||
static char *f_msg_throw_from_error_handler;
|
||||
static char *f_msg_throw_from_destructor;
|
||||
static char *f_msg_throw_ptr_to_stack;
|
||||
|
||||
// Internal memory errors.
|
||||
static char *f_msg_out_of_exception_memory;
|
||||
static char *f_msg_out_of_obj_stack_memory;
|
||||
static char *f_msg_memory_already_freed;
|
||||
|
||||
#ifdef C_API
|
||||
friend void initialize_exception();
|
||||
friend void quit_exception();
|
||||
#endif
|
||||
};
|
||||
|
||||
// includes for inline functions
|
||||
|
||||
#include "Jump_Environment.hh"
|
||||
#include "Destructable_il.hh"
|
||||
|
||||
#endif /* NATIVE_EXCEPTIONS */
|
||||
|
||||
#undef _Exceptions_hh_active
|
||||
|
||||
#endif /* _Exceptions_hh */
|
||||
/* DO NOT ADD ANY LINES AFTER THIS #endif */
|
||||
47
cde/programs/dtinfo/DtMmdb/dti_excs/Imakefile
Normal file
47
cde/programs/dtinfo/DtMmdb/dti_excs/Imakefile
Normal file
@@ -0,0 +1,47 @@
|
||||
XCOMM $TOG: Imakefile /main/12 1997/09/05 11:29:53 samborn $
|
||||
|
||||
XCOMM ** WARNING **
|
||||
XCOMM
|
||||
XCOMM The files named here may appear in many different Imakefiles.
|
||||
XCOMM If you add or remove a file, be sure to update all locations.
|
||||
XCOMM It's unfortunate, but all this redundancy serves a purpose.
|
||||
XCOMM
|
||||
XCOMM Other possible locations are:
|
||||
XCOMM .../lib/DtMmdb/Imakefile
|
||||
XCOMM .../lib/DtMmdb/<subdir>/Imakefile
|
||||
XCOMM .../programs/dtinfo/mmdb/Imakefile
|
||||
XCOMM .../programs/dtinfo/mmdb/<subdir>/Imakefile
|
||||
|
||||
#define DoNormalLib NormalLibDtMmdb
|
||||
#define DoSharedLib SharedLibDtMmdb
|
||||
#define DoDebugLib DebugLibDtMmdb
|
||||
#define DoProfileLib ProfileLibDtMmdb
|
||||
#define LibName DtMmdb
|
||||
#define SoRev SODTMMDBREV
|
||||
#define LibHeaders NO
|
||||
#define LibCreate NO
|
||||
#define LargePICTable YES
|
||||
|
||||
#define CplusplusSource YES
|
||||
DEPEND_DEFINES = $(CXXDEPENDINCLUDES)
|
||||
|
||||
#if defined(SunArchitecture) && CplusplusCompilerMajorVersion > 3
|
||||
EXCEPTION_DEFINES = -DHAS_TERMINATE
|
||||
#endif
|
||||
|
||||
DEFINES = -DC_API -DCC_VERSION=30 -DCHECK_INITIALIZED $(EXCEPTION_DEFINES)
|
||||
|
||||
BASE_SRCS = \
|
||||
Jump_Environment.C Exceptions.C Exception.C \
|
||||
Destructable.C terminate.C
|
||||
|
||||
C_API_SRCS = init.C
|
||||
|
||||
SRCS = $(BASE_SRCS) $(C_API_SRCS)
|
||||
OBJS = $(BASE_SRCS:.C=.o) $(C_API_SRCS:.C=.o)
|
||||
|
||||
#include <Library.tmpl>
|
||||
|
||||
SubdirLibraryRule($(OBJS))
|
||||
|
||||
DependTarget()
|
||||
156
cde/programs/dtinfo/DtMmdb/dti_excs/Jump_Environment.C
Normal file
156
cde/programs/dtinfo/DtMmdb/dti_excs/Jump_Environment.C
Normal file
@@ -0,0 +1,156 @@
|
||||
// $XConsortium: Jump_Environment.C /main/6 1996/10/04 09:37:00 drk $
|
||||
#ifndef NATIVE_EXCEPTIONS
|
||||
#include "Exceptions.hh"
|
||||
|
||||
Jump_Environment *Jump_Environment::g_jump_env_stack;
|
||||
|
||||
#ifdef EXC_DEBUG
|
||||
int Jump_Environment::g_level;
|
||||
#endif
|
||||
|
||||
unsigned short Unwind_Stack::g_top ;
|
||||
|
||||
#ifdef C_API
|
||||
Unwind_Record* Unwind_Stack::g_stack = 0; // inited in init.C
|
||||
#else
|
||||
Unwind_Record Unwind_Stack::g_stack[UNWIND_STACK_SIZE];
|
||||
#endif
|
||||
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// Jump_Environment - class constructor
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
Jump_Environment::Jump_Environment()
|
||||
: f_unwinding (0), f_active_exception (NULL)
|
||||
{
|
||||
PRINTF (("<%d> New Jump_Environment @ %p\n", ++g_level, this));
|
||||
// Push this on to the top of the jump env stack.
|
||||
f_next = g_jump_env_stack;
|
||||
g_jump_env_stack = this;
|
||||
}
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// class destructor
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
Jump_Environment::~Jump_Environment()
|
||||
{
|
||||
// If g_jump_env_stack == this an exception wasn't thrown.
|
||||
// (Because at throw time we set g_jump_env_stack to f_next.)
|
||||
if (g_jump_env_stack == this)
|
||||
{
|
||||
g_jump_env_stack = f_next;
|
||||
}
|
||||
// An exception was thrown in our try block.
|
||||
// An exception may have been thrown in our catch block.
|
||||
// If one was, g_jump_env_stack->f_active_exception != NULL.
|
||||
if (f_active_exception != NULL)
|
||||
{
|
||||
delete_active();
|
||||
}
|
||||
PRINTF (("<%d> Done with Jump_Environment @ %p\n",
|
||||
g_level--, this));
|
||||
}
|
||||
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// unwind - call destructors for stack based objects
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
Jump_Environment::do_unwind_and_jump (Exception *exception, int debugging)
|
||||
{
|
||||
PRINTF (("----- <%d> Unwinding stack -----\n", g_level));
|
||||
|
||||
// Remember the current exception so we can delete it later.
|
||||
f_active_exception = exception;
|
||||
|
||||
// Check for a throw out of a destructor.
|
||||
if (f_unwinding)
|
||||
{
|
||||
Exceptions::error (Exceptions::f_msg_throw_from_destructor,
|
||||
Exceptions::APPLICATION_ERROR);
|
||||
terminate();
|
||||
}
|
||||
|
||||
f_unwinding = 1;
|
||||
|
||||
// Call the destructor of each objet on the stack in reverse.
|
||||
// Length is automatically decremented as each object unregisters itself.
|
||||
while (!f_unwind_stack.empty())
|
||||
{
|
||||
PRINTF (("* Calling dtor of %p\n", f_unwind_stack.top().f_object));
|
||||
#if CC_VERSION < 30
|
||||
f_unwind_stack.top().f_object->destruct();
|
||||
#else
|
||||
f_unwind_stack.top().f_object->~Destructable();
|
||||
#endif
|
||||
}
|
||||
|
||||
// This Jump Environment is no longer needed, so we need to pull it off
|
||||
// the global jump env stack. Any new stack objects from this point
|
||||
// on must be registed in the enclosing Jump Environment scope for the
|
||||
// purposes of exceptions or otherwise. The memory associated with the
|
||||
// unwind_stack is freed when we exit the scope or throw an exception.
|
||||
g_jump_env_stack = f_next;
|
||||
PRINTF (("----- <%d> Unwind complete -----\n", g_level));
|
||||
|
||||
// Make the current exception official (it may move in the process).
|
||||
f_active_exception->make_current();
|
||||
|
||||
// Print a message about the throw point if debugging is on.
|
||||
if (debugging)
|
||||
{
|
||||
Exceptions::error_handler_t saved = Exceptions::set_error_handler (NULL);
|
||||
Exceptions::error (NULL, Exceptions::THROW_MESSAGE);
|
||||
Exceptions::set_error_handler (saved);
|
||||
}
|
||||
|
||||
// And away we go...
|
||||
longjmp();
|
||||
}
|
||||
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// delete_active - delete active exception, maybe move pending
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
Jump_Environment::delete_active()
|
||||
{
|
||||
// For starters, it's no longer the current exception.
|
||||
f_active_exception->unmake_current();
|
||||
|
||||
// We normally delete the current exception when it's enclosing
|
||||
// environment is destructed, UNLESS the same exception is being
|
||||
// rethrown to the handler above. g_jump_env_stack points to
|
||||
// the Jump_Environment that is unwinding.
|
||||
|
||||
if (f_active_exception->f_temporary &&
|
||||
(g_jump_env_stack == NULL || f_active_exception != pending_exception()))
|
||||
{
|
||||
// If there's one pending we created and a current one, we are going
|
||||
// to have to move the pending one down on our stack after
|
||||
// deleting the current one, so we need to remember where it ends.
|
||||
// If the pending exception == the current one, then we're just
|
||||
// returning to the scope of a previous exception.
|
||||
|
||||
if (g_jump_env_stack != NULL &&
|
||||
pending_exception() != NULL &&
|
||||
pending_exception()->f_temporary &&
|
||||
pending_exception() != Exception::g_current_exception)
|
||||
{
|
||||
// The length() method is only valid here!
|
||||
int length = pending_exception()->length();
|
||||
delete f_active_exception;
|
||||
Exception::relocate (&g_jump_env_stack->f_active_exception,
|
||||
length);
|
||||
}
|
||||
else // Just delete it -- no move necessary.
|
||||
{
|
||||
delete f_active_exception;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* NATIVE_EXCEPTIONS */
|
||||
139
cde/programs/dtinfo/DtMmdb/dti_excs/Jump_Environment.hh
Normal file
139
cde/programs/dtinfo/DtMmdb/dti_excs/Jump_Environment.hh
Normal file
@@ -0,0 +1,139 @@
|
||||
// $XConsortium: Jump_Environment.hh /main/6 1996/10/04 09:35:47 drk $
|
||||
#include <setjmp.h>
|
||||
|
||||
#include "Unwind_Stack.hh"
|
||||
|
||||
class Jump_Environment : public Destructable
|
||||
{
|
||||
public:
|
||||
Jump_Environment();
|
||||
|
||||
// Only unregister the environment if it hasn't been unregistered.
|
||||
// It is unregistered when an exception is thrown and stack unwound.
|
||||
~Jump_Environment();
|
||||
|
||||
static void register_object (Destructable *object);
|
||||
static void unregister_object (Destructable *object);
|
||||
|
||||
static void unwind_and_jump (Exception *current, int debugging)
|
||||
{ g_jump_env_stack->do_unwind_and_jump (current, debugging); }
|
||||
|
||||
// Must be public so setjmp can be called on it. Can't use a
|
||||
// method because of the way setjmp works.
|
||||
jmp_buf f_env;
|
||||
#ifdef SVR4
|
||||
// NOTE: this MUST follow f_env...mask bug in setjmp that overwrites our data
|
||||
// 13:59 08/03/93 - jbm
|
||||
int f_filler[8] ;
|
||||
#endif
|
||||
|
||||
private:
|
||||
void longjmp()
|
||||
{ ::longjmp (f_env, 1); }
|
||||
void do_register (Destructable *);
|
||||
void do_unregister (Destructable *);
|
||||
void do_unwind_and_jump (Exception *, int debugging);
|
||||
void delete_active();
|
||||
// The pending exception is the exception that is about to become
|
||||
// the current exception. It may be NULL if none has been thrown.
|
||||
static Exception *pending_exception()
|
||||
{ return (g_jump_env_stack->f_active_exception); }
|
||||
|
||||
private: // variables
|
||||
Exception *f_active_exception;
|
||||
Jump_Environment *f_next; // For Jump_Enviroment stacking.
|
||||
unsigned char f_unwinding; // True when unwind in progress.
|
||||
Unwind_Stack f_unwind_stack; // Stack of objects to unwind.
|
||||
|
||||
friend class Exceptions;
|
||||
static Jump_Environment *g_jump_env_stack;
|
||||
static Jump_Environment *g_used_jump_env_stack;
|
||||
#ifdef EXC_DEBUG
|
||||
static int g_level;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// do_register
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
// Register the object if it isn't a member of another Destructable
|
||||
// object. If it is a member of another, that object (or the object
|
||||
// that it's a member of) must be the last thing we registered.
|
||||
|
||||
// First check for downward growing stack. In this case the object
|
||||
// is part of another if it's address is greater than the start of
|
||||
// that other object. If it wasn't a member of that object, it's
|
||||
// address would have to be lower than that object, having been
|
||||
// created after that object.
|
||||
|
||||
// Second check for upward growing stack. In this case the object
|
||||
// is part of another if it's address is less than the end of that
|
||||
// other object.
|
||||
|
||||
// If the stack is empty, it's the first object and can't be in another.
|
||||
|
||||
inline void
|
||||
Jump_Environment::do_register (Destructable *object)
|
||||
{
|
||||
PRINTF ((" Considering object %p: ", object));
|
||||
|
||||
if (f_unwind_stack.empty() ||
|
||||
(Destructable::stack_grows_down() ?
|
||||
(unsigned long) object < f_unwind_stack.top().object_start() :
|
||||
(unsigned long) object > f_unwind_stack.top().object_end()))
|
||||
{
|
||||
PRINTF ((" -- registered\n"));
|
||||
f_unwind_stack.push (object, Destructable::g_size);
|
||||
}
|
||||
#ifdef EXC_DEBUG
|
||||
else
|
||||
{
|
||||
PRINTF ((" -- not registered\n"));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// unregister_object
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void
|
||||
Jump_Environment::do_unregister (Destructable *object)
|
||||
{
|
||||
PRINTF ((" Unregister object @ %p: ", object));
|
||||
// Don't do anything it it wasn't on the stack. It must have been
|
||||
// part of another object or was never really constructed.
|
||||
if (!f_unwind_stack.empty() && f_unwind_stack.top().f_object == object)
|
||||
{
|
||||
PRINTF ((" -- removed\n"));
|
||||
f_unwind_stack.pop();
|
||||
}
|
||||
#ifdef EXC_DEBUG
|
||||
else
|
||||
{
|
||||
PRINTF ((" -- never registered\n"));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// register/unregister
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void
|
||||
Jump_Environment::register_object (Destructable *object)
|
||||
{
|
||||
g_jump_env_stack->do_register (object);
|
||||
}
|
||||
|
||||
inline void
|
||||
Jump_Environment::unregister_object (Destructable *object)
|
||||
{
|
||||
g_jump_env_stack->do_unregister (object);
|
||||
}
|
||||
|
||||
71
cde/programs/dtinfo/DtMmdb/dti_excs/Unwind_Stack.hh
Normal file
71
cde/programs/dtinfo/DtMmdb/dti_excs/Unwind_Stack.hh
Normal file
@@ -0,0 +1,71 @@
|
||||
// $XConsortium: Unwind_Stack.hh /main/5 1996/10/04 09:34:56 drk $
|
||||
class Destructable;
|
||||
|
||||
#define UNWIND_STACK_SIZE 512
|
||||
|
||||
class Unwind_Record
|
||||
{
|
||||
public:
|
||||
Destructable *f_object;
|
||||
unsigned short f_size;
|
||||
void set (Destructable *object, unsigned int size)
|
||||
{ f_object = object; f_size = size; }
|
||||
unsigned long object_start() const
|
||||
{ return ((unsigned long) f_object); }
|
||||
unsigned long object_end() const
|
||||
{ return ((unsigned long) f_object + f_size); }
|
||||
};
|
||||
|
||||
|
||||
class Unwind_Stack
|
||||
{
|
||||
public:
|
||||
Unwind_Stack()
|
||||
{ f_bottom = g_top;
|
||||
PRINTF (("+++ New TOS = %d\n", f_bottom)); }
|
||||
|
||||
~Unwind_Stack()
|
||||
{ g_top = f_bottom;
|
||||
PRINTF (("--- Reset TOS = %d\n", g_top)); }
|
||||
|
||||
void push (Destructable *object, unsigned int size);
|
||||
|
||||
void pop()
|
||||
{ g_top--;
|
||||
PRINTF ((" Pop [ %d ]\n", g_top)); }
|
||||
|
||||
int empty() const
|
||||
{ return (g_top == f_bottom); }
|
||||
|
||||
const Unwind_Record &top() const
|
||||
{ return (g_stack[g_top-1]); }
|
||||
|
||||
private:
|
||||
unsigned short f_bottom;
|
||||
|
||||
static unsigned short g_top;
|
||||
|
||||
#ifdef C_API
|
||||
static Unwind_Record* g_stack;
|
||||
|
||||
friend void initialize_exception();
|
||||
friend void quit_exception();
|
||||
#else
|
||||
static Unwind_Record g_stack[UNWIND_STACK_SIZE];
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
inline void
|
||||
Unwind_Stack::push (Destructable *object, unsigned int size)
|
||||
{
|
||||
void terminate();
|
||||
if (g_top > UNWIND_STACK_SIZE)
|
||||
{
|
||||
Exceptions::error (Exceptions::f_msg_out_of_obj_stack_memory,
|
||||
Exceptions::INTERNAL_ERROR);
|
||||
terminate();
|
||||
}
|
||||
PRINTF ((" Push [ %d ] = %p\n", g_top, object));
|
||||
g_stack[g_top++].set (object, size);
|
||||
}
|
||||
5
cde/programs/dtinfo/DtMmdb/dti_excs/exception_init.h
Normal file
5
cde/programs/dtinfo/DtMmdb/dti_excs/exception_init.h
Normal file
@@ -0,0 +1,5 @@
|
||||
/* $XConsortium: exception_init.h /main/3 1996/06/11 16:51:51 cde-hal $ */
|
||||
|
||||
void initialize_exception();
|
||||
void quit_exception();
|
||||
|
||||
58
cde/programs/dtinfo/DtMmdb/dti_excs/init.C
Normal file
58
cde/programs/dtinfo/DtMmdb/dti_excs/init.C
Normal file
@@ -0,0 +1,58 @@
|
||||
// $XConsortium: init.cc /main/3 1996/06/11 16:51:58 cde-hal $
|
||||
|
||||
#ifndef NATIVE_EXCEPTIONS
|
||||
#include "Exceptions.hh"
|
||||
|
||||
//#define G_TEMP_SPACE_SIZE 1024
|
||||
|
||||
void initialize_exception()
|
||||
{
|
||||
|
||||
Exceptions::f_msg_internal_error = "Internal exceptions error:";
|
||||
Exceptions::f_msg_application_error = "Application exceptions error:";
|
||||
Exceptions::f_msg_throw_message = "Application threw exception:";
|
||||
|
||||
Exceptions::f_msg_not_initialized =
|
||||
"Exceptions library not initialized with INIT_EXCEPTIONS().";
|
||||
|
||||
Exceptions::f_msg_initialized_twice =
|
||||
"Attept to call INIT_EXCEPTIONS() more than once.";
|
||||
|
||||
Exceptions::f_msg_not_caught =
|
||||
"Exception not caught.";
|
||||
|
||||
Exceptions::f_msg_no_current_exception =
|
||||
"There is no current exception (for catch or rethrow).";
|
||||
|
||||
Exceptions::f_msg_throw_from_terminate =
|
||||
"Exceptions may not be thrown from terminate.";
|
||||
|
||||
Exceptions::f_msg_throw_from_error_handler =
|
||||
"Exceptions may not be thrown from error handler.";
|
||||
|
||||
Exceptions::f_msg_throw_from_destructor =
|
||||
"Exited destructor with throw while handling an exception.";
|
||||
|
||||
Exceptions::f_msg_throw_ptr_to_stack =
|
||||
"Threw a pointer to an automatic (stack-based) exceptions object.";
|
||||
|
||||
Exceptions::f_msg_out_of_exception_memory =
|
||||
"Not enough memory to allocate an exception object.";
|
||||
|
||||
Exceptions::f_msg_out_of_obj_stack_memory =
|
||||
"Not enough memory to allocate object stack.";
|
||||
|
||||
Exceptions::f_msg_memory_already_freed =
|
||||
"Tried to alloc or realloc pool memory that was previously freed.";
|
||||
|
||||
Unwind_Stack::g_stack = new Unwind_Record[UNWIND_STACK_SIZE];
|
||||
Exception::g_temp_space = new char[G_TEMP_SPACE_SIZE];
|
||||
Exception::g_next_avail = Exception::g_temp_space;
|
||||
}
|
||||
|
||||
void quit_exception()
|
||||
{
|
||||
delete Unwind_Stack::g_stack;
|
||||
}
|
||||
|
||||
#endif
|
||||
41
cde/programs/dtinfo/DtMmdb/dti_excs/new_delete_simple.h
Normal file
41
cde/programs/dtinfo/DtMmdb/dti_excs/new_delete_simple.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/* $XConsortium: new_delete_simple.h /main/3 1996/06/11 16:52:04 cde-hal $ */
|
||||
|
||||
|
||||
#ifndef _new_delete_simple_h
|
||||
#define _new_delete_simple_h 1
|
||||
|
||||
|
||||
#define NEW_AND_DELETE_SIGNATURES(class_name) \
|
||||
void* operator new( size_t ); \
|
||||
void* operator new( size_t, void* ); \
|
||||
void operator delete( void* )
|
||||
|
||||
#ifdef C_API
|
||||
#include <stdlib.h>
|
||||
|
||||
#define NEW_AND_DELETE_BODIES_SIMPLE(class_name) \
|
||||
\
|
||||
void* class_name::operator new( size_t sz )\
|
||||
{\
|
||||
return (void*)malloc(sz); \
|
||||
}\
|
||||
\
|
||||
void* class_name::operator new( size_t sz, void* ptr )\
|
||||
{\
|
||||
return (void*)ptr; \
|
||||
}\
|
||||
\
|
||||
void class_name::operator delete( void* p )\
|
||||
{\
|
||||
::operator delete(p); \
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
#include <new.h>
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
51
cde/programs/dtinfo/DtMmdb/dti_excs/terminate.C
Normal file
51
cde/programs/dtinfo/DtMmdb/dti_excs/terminate.C
Normal file
@@ -0,0 +1,51 @@
|
||||
// $TOG: terminate.C /main/4 1997/09/05 11:30:17 samborn $
|
||||
#if !defined(NATIVE_EXCEPTIONS) && !defined(HAS_TERMINATE)
|
||||
#include "Exceptions.hh"
|
||||
|
||||
typedef void (*PFV)();
|
||||
|
||||
static PFV _terminate_handler = NULL;
|
||||
|
||||
PFV
|
||||
set_terminate (PFV handler)
|
||||
{
|
||||
PFV old_handler = _terminate_handler;
|
||||
|
||||
_terminate_handler = handler != NULL ? handler : NULL;
|
||||
|
||||
return (old_handler);
|
||||
}
|
||||
|
||||
void
|
||||
terminate()
|
||||
{
|
||||
if (_terminate_handler != NULL)
|
||||
{
|
||||
// Reset terminate handler to NULL before handling to
|
||||
// avoid potential recursive calls due to exceptions
|
||||
// abuse in the terminate handler.
|
||||
PFV handler = _terminate_handler;
|
||||
_terminate_handler = NULL;
|
||||
try
|
||||
{
|
||||
(*handler)();
|
||||
}
|
||||
catch_any()
|
||||
{
|
||||
Exceptions::error (Exceptions::f_msg_throw_from_terminate,
|
||||
Exceptions::APPLICATION_ERROR);
|
||||
}
|
||||
end_try;
|
||||
}
|
||||
|
||||
abort();
|
||||
}
|
||||
#else
|
||||
|
||||
#ifdef hpux
|
||||
// HPUX doesn't define the set_terminate function from the ARM.
|
||||
typedef void (*PFV)();
|
||||
PFV set_terminate (PFV) { return (0); }
|
||||
#endif
|
||||
|
||||
#endif /* NATIVE_EXCEPTIONS */
|
||||
9
cde/programs/dtinfo/DtMmdb/dti_excs/terminate.hh
Normal file
9
cde/programs/dtinfo/DtMmdb/dti_excs/terminate.hh
Normal file
@@ -0,0 +1,9 @@
|
||||
// $XConsortium: terminate.hh /main/3 1996/06/11 16:52:15 cde-hal $
|
||||
#ifndef _terminate_hh
|
||||
#define _terminate_hh
|
||||
|
||||
void (*set_terminate (void(*)()))();
|
||||
void terminate();
|
||||
|
||||
#endif /* _terminate_hh */
|
||||
/* DO NOT ADD ANY LINES AFTER THIS #endif */
|
||||
Reference in New Issue
Block a user