221 lines
5.7 KiB
C++
221 lines
5.7 KiB
C++
/*
|
|
* CDE - Common Desktop Environment
|
|
*
|
|
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
|
|
*
|
|
* These libraries and programs are free software; you can
|
|
* redistribute them and/or modify them under the terms of the GNU
|
|
* Lesser General Public License as published by the Free Software
|
|
* Foundation; either version 2 of the License, or (at your option)
|
|
* any later version.
|
|
*
|
|
* These libraries and programs are distributed in the hope that
|
|
* they will be useful, but WITHOUT ANY WARRANTY; without even the
|
|
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
* PURPOSE. See the GNU Lesser General Public License for more
|
|
* details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with these libraries and programs; if not, write
|
|
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
|
|
* Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
#include <ctype.h>
|
|
|
|
#define G_TEMP_SPACE_SIZE 1024
|
|
|
|
#define CASTEXCEPT
|
|
|
|
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.)
|
|
|
|
static void *operator new (size_t size)
|
|
{ return (::operator new (size)); }
|
|
|
|
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)
|
|
#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); \
|
|
((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...
|