#ifdef AIX_PROD
/* @(#)79	1.8  src/threads/exc_handling.h, threads.src, os2dce21.dss, 960602a.1  4/19/96  11:48:48 */
/*
 * COMPONENT_NAME: threads.src
 *
 * FUNCTIONS:
 *
 * ORIGINS: 72
 *
 * OBJECT CODE ONLY SOURCE MATERIALS
 *
 */
#endif /* AIX_PROD */
/*
 * @OSF_COPYRIGHT@
 * COPYRIGHT NOTICE
 * Copyright (c) 1990, 1991, 1992, 1993, 1994 Open Software Foundation, Inc.
 * ALL RIGHTS RESERVED (DCE).  See the file named COPYRIGHT.DCE for
 * the full copyright text.
 *
 * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
 * Burlington, MA, USA
 */
/*
 * HISTORY
 * $Log: exc_handling.h,v $
 * Revision 1.2.21.2  1994/06/09  13:39:18  devsrc
 * 	 CR10892 - fix copyright in file
 * 	[1994/06/09  13:29:04  devsrc]
 *
 * Revision 1.2.21.1  1994/04/01  20:18:04  jd
 * 	Fist drop of code cleanup
 * 	[1994/03/28  19:19:50  jd]
 * 
 * Revision 1.2.19.1  1993/10/05  21:38:49  ohara
 * 	SNI SVR4 ref port 8596
 * 	[1993/09/15  22:14:05  ohara]
 * 
 * Revision 1.2.16.3  1993/06/10  19:50:56  sommerfeld
 * 	On HP-UX: Set _EXC_BAR_JMP_ to true
 * 		  Add exc_{setjmp|longjmp} macros for HP platforms.
 * 	[1993/06/08  16:27:21  hopkins]
 * 
 * 	   Add new #define, _exc_jmpbuf_type, for cast in TRY macro
 * 	   Must be double on HP-UX, int on other platforms.
 * 	   This should probably be moved to a machine-specific header file
 * 	   as part of code cleanup.
 * 	   [1993/04/23  22:10:11  hopkins]
 * 	[1993/06/04  21:24:09  sommerfeld]
 * 
 * Revision 1.2.16.2  1993/05/24  20:50:48  cjd
 * 	Submitting 102-dme port to 103i
 * 	[1993/05/24  20:18:21  cjd]
 * 
 * Revision 1.2.14.2  1993/05/11  22:02:43  jd
 * 	Initial 486 port.
 * 	[1993/05/11  21:45:00  jd]
 * 
 * Revision 1.2.5.5  1993/02/01  22:32:41  hinman
 * 	[hinman@sni] - Final merge before bsubmit
 * 	[1993/01/31  17:34:22  hinman]
 * 
 * 	[hinman] - Check in merged SNI version
 * 	[1993/01/11  16:24:12  hinman]
 * 
 * Revision 9.5.1.10  93/01/08  11:27:43  devsrc
 * 	[raj] Fix copyright  notice
 * 
 * Revision 9.5.1.9  92/10/26  12:41:58  bein
 * 	PTC - fixed garbage in file.
 * 
 * Revision 9.5.4.2  92/10/26  10:28:21  bein
 * 	PTC - fixed last set of changes for PYRMIPS platform.
 * 
 * Revision 9.5.1.8  92/10/06  12:14:35  blurie
 * 	Use setjmp() instead of sigsetjmp() on SVR4, MX300I.
 * 	[92/10/06  12:13:36  blurie]
 * 
 * Revision 9.5.1.7  92/09/30  12:43:34  root
 * 	Acceptance of OSF rev 1.2.5.3
 * 
 * Revision 9.12.1.2  92/09/30  10:39:19  hinman
 * 	Auto checkin of OSF rev 1.2.5.3
 * 
 * Revision 1.2.5.3  1992/09/29  20:16:38  devsrc
 * 	[OT 5373]    SNI/SVR4 merge.
 * 	[1992/09/17  21:01:06  sekhar]
 * 
 * Revision 1.2.5.2  1992/09/03  14:43:11  bolinger
 * 	Replace current source file with equivalent from DEC BL10+
 * 	source base, as originally integrated in the
 * 	nosupport/threads_bl10 tree.  (See OT defect 5300.)
 * 	[1992/09/02  14:08:49  bolinger]
 * 
 * Revision 1.1.2.3  1992/08/14  20:23:59  bolinger
 * 	Bring forward 1.0.1 revision 1.2.3.4 (fix for OT defect 2886).
 * 	[1992/08/10  16:42:15  bolinger]
 * 
 * Revision 1.1.2.2  1992/05/09  00:19:57  bolinger
 * 	BL10 CMA sources from DEC.
 * 	[1992/05/09  00:19:40  bolinger]
 * 
 * Revision 1.2.3.4  1992/05/11  21:32:15  bolinger
 * 	Correct log.
 * 	[1992/05/11  21:27:01  bolinger]
 * 
 * 	Fix for OT defect 2886: enable use of _setjmp/_longjmp on
 * 	both reference platforms.  This avoids needless (and sometimes
 * 	pernicious) save/restore of process signal mask, and nets
 * 	a nice performance gain into the bargain.
 * 	[1992/05/11  13:13:27  bolinger]
 * 
 * Revision 1.2.3.3  1992/04/24  17:49:48  bolinger
 * 	Fix for OT defect 2142 -- typo in _EXC_HARDWARE_ use.
 * 	[1992/04/24  17:15:35  bolinger]
 * 
 * Revision 1.2.3.2  1992/04/22  15:49:48  keane
 * 	Remove dependency on CMA configuration symbol
 * 	[1992/04/22  13:21:44  keane]
 * 
 * Revision 1.2  1992/01/19  22:14:48  devrcs
 * 	Dropping DCE1.0 OSF1_misc port archive
 * 
 * $EndLog$
 */
/*
 *	src/threads/exc_handling.h, threads.src, os2dce21.dss, 960602a.1	(DEC OSF/1)	4/19/96
 */
/*
 *  Copyright (c) 1989, 1992 by
 *  Digital Equipment Corporation, Maynard Massachusetts.
 *  All rights reserved.
 *
 *  This software is furnished under a license and may be used and  copied
 *  only  in  accordance  with  the  terms  of  such  license and with the
 *  inclusion of the above copyright notice.  This software or  any  other
 *  copies  thereof may not be provided or otherwise made available to any
 *  other person.  No title to and ownership of  the  software  is  hereby
 *  transferred.
 *
 *  The information in this software is subject to change  without  notice
 *  and  should  not  be  construed  as  a commitment by DIGITAL Equipment
 *  Corporation.
 *
 *  DIGITAL assumes no responsibility for the use or  reliability  of  its
 *  software on equipment which is not supplied by DIGITAL.
 */

/*
 *  FACILITY:
 *
 *	DECthreads exception services
 *
 *  FILENAME:
 *
 * 	EXC_HANDLING.H
 *
 *  ABSTRACT:
 *
 *	Header file for exception handling in C
 *
 *  AUTHORS:
 *
 *	Eric Roberts
 *	Bob Conti
 *	Dave Butenhof
 *
 *  CREATION DATE:
 *
 *	15 March 1989
 *
 *  MODIFIED BY:
 *
 *	Dave Butenhof
 *	Bob Conti
 *	Paul Curtin
 *	Webb Scales
 *
 *      6008  Sy Lin     2 Feb. 94  -  supported other C++;
 *                                      modified setjmp/longjmp
 *      8422  Domingo Hidalgo  15 March 94  -  supported other C++; WATCOM
 *
 *      8832  -  make set/long  jmp  backward compatible
 *
 *      8903  -  followup code changes for set/long jmp
 *
 *      9019  -  make  downward compatible as default
 */


#ifndef EXC_HANDLING
# define EXC_HANDLING   1

#ifdef IBMOS2
#ifndef DCEAPI
#include <dce/dcedef.h>
#endif
#endif	/*	IBMOS2	*/
/*
 *  INCLUDE FILES
 */

#define _EXC__CC        1
#define _EXC__VAXC      2
#define _EXC__DECC      3
#define _EXC__CFRONT    4
#define _EXC__GCC       5
#define _EXC__DECCPLUS  6
#define _EXC__GCPLUS    7

/*
 * Test for C++ compilers before C compilers because Glockenspiel C++ also
 * defines symbols for the VAX C compiler and this could be the case for
 * other C++/C compiler combinations
 */
#ifndef _EXC_COMPILER_
# if defined(__cplusplus)               /* test for other C++ compilers first */
#  if defined(__DECCXX)
#   define _EXC_COMPILER_       _EXC__DECCPLUS
#  else
#   define _EXC_COMPILER_       _EXC__CFRONT
#  endif
# elif defined(vaxc) || defined(VAXC) || defined(__vaxc) || defined(__VAXC)
#  define _EXC_COMPILER_        _EXC__VAXC
# elif defined(__decc) || defined(__DECC)
#  define _EXC_COMPILER_        _EXC__DECC
# elif defined(__GNUC__)
#  define _EXC_COMPILER_        _EXC__GCC
# else
#  define _EXC_COMPILER_        _EXC__CC
# endif
#endif

/*
 * Name of the hardware platform
 */
#define _EXC__MIPS      1
#define _EXC__VAX       2
#define _EXC__M68K      3
#define _EXC__HPPA      4
#define _EXC__IBMR2     5
#define _EXC__ALPHA     6
#ifdef IBMOS2
#define _EXC__INTEL80x86    7
#define _EXC__MX300I	10
#else	/*	!IBMOS2	*/
#define _EXC__MX300I	7
#endif	/*	!IBMOS2	*/
#define _EXC__CPLMIPS	8
#define _EXC__I386      9

#ifndef _EXC_HARDWARE_
# if defined(vax) || defined (VAX) || defined(__vax) || defined(__VAX)
#  define       _EXC_HARDWARE_  _EXC__VAX
# endif
# if defined(mips) || defined(MIPS) || defined(__mips) || defined(__MIPS)
#  if !defined(SNI_DCOSX)
#  define       _EXC_HARDWARE_  _EXC__MIPS
#  endif    /* !SNI_DCOSX */
# endif
# if defined(m68k) || defined(m68000) || defined(_ISP__M68K) || defined(M68000) || defined(mc68000)
#  define       _EXC_HARDWARE_  _EXC__M68K
# endif
# if defined(hp9000s300) || defined(__hp9000s300)
#  define       _EXC_HARDWARE_  _EXC__M68K
# endif
# if defined(__hppa)
#  define       _EXC_HARDWARE_  _EXC__HPPA
# endif
# if defined(_IBMR2)
#  define       _EXC_HARDWARE_  _EXC__IBMR2
# endif
# if defined(__ALPHA) || defined(__alpha)
#  define       _EXC_HARDWARE_  _EXC__ALPHA
# endif
# if defined(SNI_MX300I)
#  define _EXC_HARDWARE_ _EXC__MX300I
# endif
# if defined(SNI_DCOSX)
#  define _EXC_HARDWARE_ _EXC__CPLMIPS
# endif
# if !defined(SNI_SVR4)
#  if defined(__i386)
#   define       _EXC_HARDWARE_  _EXC__I386
#  endif
# endif
# if defined(INTEL80x86)
#  define _EXC_HARDWARE_ _EXC__INTEL80x86
# endif
# ifndef _EXC_HARDWARE_
   !!!Error: _EXC_HARDWARE_ not set
# endif
#endif

#define _EXC__UNIX      1
#define _EXC__VMS       2
#ifdef IBMOS2
#define _EXC__OS2       3
#define _EXC__SVR4		4
#else	/*	!IBMOS2	*/
#define _EXC__SVR4  3
#endif	/*	!IBMOS2	*/

#ifndef _EXC_OS_
# if defined(IBMOS2)
#  define       _EXC_OS_         _EXC__OS2
# endif
#endif
#ifndef _EXC_OS_
# if defined(unix) || defined(__unix) || defined(_AIX) || defined(__OSF__) || defined(__osf__) || defined(SNI_SVR4)
#  define	_EXC_OS_	_EXC__UNIX
#  if defined(SNI_SVR4)
#    define _EXC_UNIX_TYPE _EXC__SVR4
#  endif
# endif
# if defined(vms) || defined(__vms) || defined(VMS) || defined(__VMS) || defined(__vms__)
#  define       _EXC_OS_        _EXC__VMS
# endif
# ifndef _EXC_OS_
   !!!Error: _EXC_OS_ not set
# endif
#endif

/*
 * Combined platform (OS + hardware)
 */
#define _EXC__MIPS_UNIX         1
#define _EXC__VAX_VMS           2
#define _EXC__VAX_UNIX          3
#define _EXC__M68K_UNIX         4
#define _EXC__HPPA_UNIX         5
#define _EXC__IBMR2_UNIX        6
#define _EXC__ALPHA_UNIX        7
#define _EXC__ALPHA_VMS         8
#ifdef IBMOS2
#define _EXC__INTEL80x86_OS2    9
#define _EXC__SINIX_MX300I	   12
#else	/*	!IBMOS2	*/
#define _EXC__SINIX_MX300I		9
#endif	/*	!IBMOS2	*/
#define _EXC__DCOSX_MIPS       10
#define _EXC__I386_UNIX        11

#ifndef _EXC_PLATFORM_
# if _EXC_OS_ == _EXC__UNIX
#  if _EXC_HARDWARE_ == _EXC__MIPS
#   define _EXC_PLATFORM_       _EXC__MIPS_UNIX
#  endif
#  if _EXC_HARDWARE_ == _EXC__VAX
#   define _EXC_PLATFORM_       _EXC__VAX_UNIX
#  endif
#  if _EXC_HARDWARE_ == _EXC__M68K
#   define _EXC_PLATFORM_       _EXC__M68K_UNIX
#  endif
#  if _EXC_HARDWARE_ == _EXC__HPPA
#   define _EXC_PLATFORM_       _EXC__HPPA_UNIX
#  endif
#  if _EXC_HARDWARE_ == _EXC__IBMR2
#   define _EXC_PLATFORM_       _EXC__IBMR2_UNIX
#  endif
#  if _EXC_HARDWARE_ == _EXC__ALPHA
#   define _EXC_PLATFORM_       _EXC__ALPHA_UNIX
#  endif
#  if (_EXC_HARDWARE_ == _EXC__MX300I) && (_EXC_UNIX_TYPE == _EXC__SVR4)
#   define _EXC_PLATFORM_ _EXC__SINIX_MX300I
# endif
#  if (_EXC_HARDWARE_ == _EXC__CPLMIPS)
#   define _EXC_PLATFORM_	_EXC__DCOSX_MIPS
#  endif
#  if (_EXC_HARDWARE_ == _EXC__I386)
#   define _EXC_PLATFORM_       _EXC__I386_UNIX
#  endif
# endif
# if _EXC_OS_ == _EXC__VMS
#  if _EXC_HARDWARE_ == _EXC__VAX
#   define _EXC_PLATFORM_       _EXC__VAX_VMS
#  endif
#  if _EXC_HARDWARE_ == _EXC__ALPHA
#   define _EXC_PLATFORM_       _EXC__ALPHA_VMS
#  endif
# endif
# if defined(IBMOS2) && (_EXC_HARDWARE_ ==  _EXC__INTEL80x86)
#  define _EXC_PLATFORM_        _EXC__INTEL80x86_OS2
# endif
# ifndef _EXC_PLATFORM_
   !!!Error: _EXC_PLATFORM_ not set
# endif
#endif

/*
 * Name of the software vendor (alphabetical order :-) )
 */
#define _EXC__APOLLO    1
#define _EXC__DIGITAL   2
#define _EXC__HP        3
#define _EXC__IBM       4
#define _EXC__OSF       5
#define _EXC__SUN       6
#define _EXC__SNI       7
#define _EXC__PTC       8

#ifndef _EXC_VENDOR_
# ifdef apollo
#  define       _EXC_VENDOR_    _EXC__APOLLO
# endif
# if _EXC_OS_ == _EXC__VMS
#  define       _EXC_VENDOR_    _EXC__DIGITAL
# endif
# if defined(ultrix) || defined(__ULTRIX) || defined (__ultrix)
#  define       _EXC_VENDOR_    _EXC__DIGITAL
# endif
# if defined(__osf__) && !defined(__OSF__) && (_EXC_HARDWARE_ == _EXC__MIPS)
#  define       _EXC_VENDOR_    _EXC__DIGITAL
# endif
# if defined(__osf__) && !defined(__OSF__) && (_EXC_HARDWARE_ == _EXC__ALPHA)
#  define       _EXC_VENDOR_    _EXC__DIGITAL
# endif
# if defined(hpux) || defined(__hpux)
#  define       _EXC_VENDOR_    _EXC__HP
# endif
# ifdef _IBMR2
#  define       _EXC_VENDOR_    _EXC__IBM
# endif
# ifdef IBMOS2
#  define       _EXC_VENDOR_    _EXC__IBM
# endif
# ifdef sun
#  define       _EXC_VENDOR_    _EXC__SUN
# endif
# ifdef SNI_SINIX
#  define   _EXC_VENDOR_    _EXC__SNI
# endif
# ifdef SNI_DCOSX
#  define   _EXC_VENDOR_    _EXC__PTC
# endif
# if defined (__OSF__) && !defined (_EXC_VENDOR_)
#  define       _EXC_VENDOR_    _EXC__OSF
# endif
# ifndef _EXC_VENDOR_
   !!!Error: _EXC_VENDOR_ not set
# endif
#endif

/*
 * This controls whether ANSI C function prototypes are used for EXC
 * interfaces.
 */
#ifndef _EXC_PROTO_
# if defined(__STDC__) || defined(IBMOS2)
#  define _EXC_PROTO_           1
# endif
# if _EXC_COMPILER_ == _EXC__DECC
#  define _EXC_PROTO_           1
# endif
# if _EXC_COMPILER_ == _EXC__GCC
#  define _EXC_PROTO_           1
# endif
# if _EXC_COMPILER_ == _EXC__CFRONT
#  define _EXC_PROTO_           1
# endif
# if _EXC_COMPILER_ == _EXC__DECCPLUS
#  define _EXC_PROTO_           1
# endif
# if _EXC_COMPILER_ == _EXC__GCPLUS
#  define _EXC_PROTO_           1
# endif
# if _EXC_COMPILER_ == _EXC__VAXC
#  define _EXC_PROTO_           1
# endif
# if (_EXC_VENDOR_ == _EXC__DIGITAL) && (_EXC_HARDWARE_ == _EXC__MIPS)
#  define _EXC_PROTO_           1
# endif
# if _EXC_VENDOR_ == _EXC__APOLLO
#  define _EXC_PROTO_           1
# endif
# if (_EXC_VENDOR_ == _EXC__HP) && (_EXC_HARDWARE_ == _EXC__HPPA)
#  define _EXC_PROTO_           1
# endif
# if _EXC_HARDWARE_ == _EXC__IBMR2
#  define _EXC_PROTO_           1
# endif
# if _EXC_PLATFORM_ == _EXC__SINIX_MX300I
#  define _EXC_PROTO_       1
# endif
# if _EXC_PLATFORM_ == _EXC__DCOSX_MIPS
#  define _EXC_PROTO_       1
# endif
# if _EXC_HARDWARE_ == _EXC__INTEL80x86
#  define _EXC_PROTO_           1
# endif
/* Otherwise, _EXC_PROTO_ is undefined, which means do not use prototypes. */
#endif

/*
 * MIPS C on DEC OSF/1 sets __osf__ but not __OSF__; but gcc on "raw" OSF/1
 * sets __OSF__ but not __osf__. This little ditty provides a bridge.
 */
#if defined (__OSF__) && !defined (__osf__)
# define __osf__
#endif

#define _EXC__OS_AIX    1
#define _EXC__OS_OSF    2
#define _EXC__OS_BSD    3
#define _EXC__OS_SYSV   4
#define _EXC__OS_VMS    5
#define _EXC__OS_OS2    6

#ifndef _EXC_OSIMPL_
# if _EXC_OS_ == _EXC__VMS
#  define _EXC_OSIMPL_          _EXC__OS_VMS
# else
#  if defined (__osf__)
#   define _EXC_OSIMPL_         _EXC__OS_OSF
#  else
#   if _EXC_VENDOR_ == _EXC__IBM && ( _EXC_HARDWARE_ == _EXC__IBMR2)
#    define _EXC_OSIMPL_        _EXC__OS_AIX
#   else
#    if (_EXC_VENDOR_ == _EXC__IBM) && (_EXC_HARDWARE_ == _EXC__INTEL80x86)
#     define _EXC_OSIMPL_                _EXC__OS_OS2
#    else
#     if _EXC_VENDOR_ == _EXC__SUN
#      define _EXC_OSIMPL_       _EXC__OS_SYSV
#     else
#      define _EXC_OSIMPL_       _EXC__OS_BSD
#     endif
#    endif
#   endif
#  endif
# endif
#endif

#ifndef _EXC_VOLATILE_
# if _EXC_PLATFORM_ == _EXC__VAX_UNIX
#  if _EXC_COMPILER_ == _EXC__CC
#   define _EXC_VOLATILE_
#   define _EXC_VOLATILE_FLAG_          0
#  endif
# endif
# if _EXC_VENDOR_ == _EXC__SUN
#  define _EXC_VOLATILE_
#  define _EXC_VOLATILE_FLAG_           0
# endif
# if _EXC_COMPILER_ == _EXC__CFRONT
#  define _EXC_VOLATILE_
#  define _EXC_VOLATILE_FLAG_           0
# endif
#ifndef _EXC_VOLATILE_
#  define _EXC_VOLATILE_                volatile
#  define _EXC_VOLATILE_FLAG_           1
# endif
#endif

#ifndef _EXC_IMPORT_
# if (_EXC_OS_ == _EXC__VMS) && (_EXC_HARDWARE_ == _EXC__VAX)
#  if _EXC_COMPILER_ == _EXC__DECCPLUS
#   pragma __extern_model __save
#   pragma __extern_model __strict_refdef
#   define _EXC_IMPORT_ extern
#  else
#   define _EXC_IMPORT_ globalref
#  endif
# else
#  define _EXC_IMPORT_ extern
# endif
#endif

#ifdef _EXC_PROTO_
#define _EXC_PROTOTYPE_(arg)    arg
#else
#define _EXC_PROTOTYPE_(arg)    ()
#endif

/*
 * NOTE: on U*IX systems, these status codes must be kept unique from
 * "Enums".  We do this arbitrarily by setting some high order bits which
 * happen to be the same as we use on VMS. Apollo systems use different
 * error numbering scheme, and override this.
 */
#if _EXC_VENDOR_ == _EXC__APOLLO
# define exc_facility_c 0x03c0000
# define _EXC_STATUS_(val, sev) ((exc_int_t)(exc_facility_c + (val)))
#endif
#if _EXC_OS_ == _EXC__VMS
# define exc_facility_c 00020100000
# define _EXC_STATUS_(val, sev) \
        ((exc_int_t)(exc_facility_c | ((val) << 3) | (sev)))
#endif
#ifndef _EXC_STATUS_
# define _EXC_DCE_PREFIX_       0x177db000
# define exc_facility_c         _EXC_DCE_PREFIX_
# define _EXC_STATUS_(val, sev) \
        ((exc_int_t)(_EXC_DCE_PREFIX_ | (val)))
#endif

#include <setjmp.h>

#ifdef IBMOS2
void DCEAPI pthread_inst_longjmp( void * lgjmp );

#define pthread_define_longjmp(mylongjmp)	\
void DCEAPI mylongjmp(jmp_buf env, int val)	\
{											\
	longjmp(env,val);						\
}
#endif	/*	IBMOS2	*/

/*
 * Define a symbol that specifies whether exception handling should use the
 * standard setjmp() and longjmp() functions, or the alternate _setjmp() and
 * _longjmp().  The latter are faster, as they don't save/restore the signal
 * mask (and therefore require no kernel calls).  However, _setjmp() and
 * _longjmp() are not standard, and therefore may not be available
 * everywhere. Also, there may be some platforms where failing to save signal
 * state could break exception handling. For both reasons, we enable use of
 * the optimized functions only where we know for sure they are both
 * available and appropriate.
 */
#ifndef _EXC_BAR_JMP_
/*
 * The current intent is to enable this feature for all Apollo O.S.'s,
 * DEC's OSF/1 and Ultrix, AIX, and OSF's OSF/1.
 */
 /*
 *	On SVR4, we use setjmp() if _EXC_BAR_JMP_ is set, otherwise use
 *	sigsetjmp().
 */
/*
 *	Set _EXC_BAR_JMP_ to 1 on HP platforms.
 */
# if (_EXC_VENDOR_ == _EXC__APOLLO) || ((_EXC_VENDOR_ == _EXC__DIGITAL) && (_EXC_OS_ == _EXC__UNIX)) || _EXC_PLATFORM_ == _EXC__IBMR2_UNIX || _EXC_VENDOR_ == _EXC__OSF || (_EXC_PLATFORM_ == _EXC__SINIX_MX300I) || (_EXC_VENDOR_ == _EXC__HP)
#  define _EXC_BAR_JMP_ 1
# endif
# ifndef _EXC_BAR_JMP_
#  define _EXC_BAR_JMP_ 0
# endif
#endif

#if _EXC_OS_ == _EXC__VMS
# if _EXC_HARDWARE_ == _EXC__VAX
   typedef int cma__t_jmp_buf[14];
   extern int cma$$save_exc_context (_EXC_VOLATILE_ int *);
# else
#  include <ints.h>
   typedef uint64 cma__t_jmp_buf[(14+8+3)];
   extern int cma$$save_exc_context (_EXC_VOLATILE_ uint64 *);
# endif
# define exc_setjmp(__env)      cma$$save_exc_context((__env))
#else
#ifdef IBMOS2
   typedef int cma__t_jmp_buf[8];        /* IBM C Set++ equivalent - DSH  */
   typedef int cma__t_jmp_buf_new[11];   /* Jump buffer for OS/2 DCE - RPP*/
#else	/*	!IBMOS2	*/
# if _EXC_UNIX_TYPE == _EXC__SVR4
#  if _EXC_BAR_JMP_
    typedef jmp_buf cma__t_jmp_buf;
#  else
    typedef sigjmp_buf cma__t_jmp_buf;
#  endif
# else
  typedef jmp_buf cma__t_jmp_buf;
# endif
#endif	/*	!IBMOS2	*/
# if _EXC_BAR_JMP_
#  if _EXC_OSIMPL_ == _EXC__OS_OSF
    /*
     * OSF/1 already provides prototypes for _setjmp and _longjmp in
     * /usr/include/setjmp.h; the prototypes here should be compatible, so
     * we'll just cast the volatile jump buffer inside the exc_setjmp macro
     * instead of defining an appropriate prototype as we do elsewhere.
     */
    extern int _setjmp _EXC_PROTOTYPE_ ((jmp_buf));
    extern void _longjmp _EXC_PROTOTYPE_ ((jmp_buf, int));
#   define exc_setjmp(__env)            _setjmp ((int *)(__env))
#   define exc_longjmp(__env,__val)     _longjmp((int *)(__env),(__val))
#  elif (_EXC_UNIX_TYPE == _EXC__SVR4)
#   define exc_setjmp(__env)     	setjmp ((__env))
#   define exc_longjmp(__env,__val) longjmp((__env),(__val))
#  elif (_EXC_VENDOR_ == _EXC__HP)
#   define exc_setjmp(__env)		_setjmp ((__env))
#   define exc_longjmp(__env,__val)	_longjmp((__env),(__val))
#  else
    extern int _setjmp _EXC_PROTOTYPE_ ((_EXC_VOLATILE_ int *));
    extern void _longjmp _EXC_PROTOTYPE_ ((_EXC_VOLATILE_ int *, int));
#   define exc_setjmp(__env)            _setjmp ((__env))
#   define exc_longjmp(__env,__val)     _longjmp((__env),(__val))
#  endif
# else
#  if (_EXC_UNIX_TYPE == _EXC__SVR4)
#   define exc_setjmp(__env)     sigsetjmp ((__env),0)
#   define exc_longjmp(__env,__val)  siglongjmp((__env),(__val))
#  else
#   ifdef IBMOS2
void DCEAPI longjmp_dce( cma__t_jmp_buf );
#   define exc_longjmp(__env)           longjmp_dce((__env))

#    ifndef _IBMOS2_DCE_NOFLOAT

#     if defined(__IBMC__) || defined(__IBMCPP__)

#include <setjmp.h>
#   define exc_setjmp(__env)   setjmp ((__env))

#     else    /* Use compiler safe version */
int DCEAPI setjmp_safe( cma__t_jmp_buf );
#   define exc_setjmp(__env)  setjmp_safe((__env))
#     endif  /* End testing  __IBMC__ or __IBMCPP__   */

#    else   /* _IBMOS2_DCE_NOFLOAT defined   */

int DCEAPI setjmp_nfp( cma__t_jmp_buf );
#   define exc_setjmp(__env)  setjmp_nfp((__env))

#    endif   /* _IBMOS2_DCE_NOFLOAT    */
#   else	/*	!IBMOS2	*/
#   define exc_setjmp(__env)            setjmp ((__env))
#   define exc_longjmp(__env,__val)     longjmp((__env),(__val))
#   endif	/*	!IBMOS2	*/
#  endif
# endif /*!_EXC_BAR_JMP_*/
#endif /*!_EXC_OS_ == _EXC__VMS*/

typedef char *exc_address_t;

/*
 * Use the most efficient code available to determine the address of the
 * current procedure frame on VAX VMS systems (which we need to integrate
 * well with native VAX VMS condition handling).
 *
 * - VAX C under VAX VMS supports instruction "builtins" to access general
 * registers. Since it requires a "#pragma", which some old cpp versions
 * can't parse, it's hidden in a separate file.
 *
 * - GCC supports an "asm" statement that generates inline assembly code.
 *
 * - Otherwise, declare an extern function (part of DECthreads' assembly
 * code) that will return the value.
 */
#if _EXC_OS_ == _EXC__VMS
# if _EXC_HARDWARE_ == _EXC__VAX
#  if _EXC_COMPILER_ == _EXC__VAXC
#   include <exc_handling_vms.h>
#  elif _EXC_COMPILER_ == _EXC__GCC
#   define cma$exc_fetch_fp() \
    ({ int frameptr; \
    asm volatile ("movl fp, %0" : "=g" (frameptr)); \
    frameptr; })
#  else
   extern exc_address_t cma$exc_fetch_fp (void);
#  endif
# else
   extern exc_address_t cma$exc_fetch_fp (void);
# endif
#endif

/*
 * Define all of the status codes used by DECthreads.
 *
 * For VMS, these must remain in synch with the CMA_MESSAGE.GNM message file.
 *
 * These values cannot be altered after they have shipped in some DECthreads
 * release.
 */

/*
 * EXC facility messages
 */
#define exc_s_exception         _EXC_STATUS_(1, 4)
#define exc_s_exccop            _EXC_STATUS_(2, 4)
#define exc_s_uninitexc         _EXC_STATUS_(3, 4)
#define exc_s_unkstatus         _EXC_STATUS_(128, 4)
#define exc_s_exccoplos         _EXC_STATUS_(129, 4)

/*
 * These should be set to match with underlying system exception codes on
 * platforms where that is appropriate (e.g., ss$_ codes on VMS).
 */
#if _EXC_OS_ == _EXC__VMS
/*
 * A few of these codes are somewhat imaginary, since VMS doesn't support
 * condition codes that very closely approximate the sense of some UNIX
 * signals.  SIGTRAP, SIGIOT, and SIGEMT have no clear parallels, and the
 * values chosen are fairly arbitrary.  For two others, we chose what seemed
 * close equivalents: SIGPIPE becomes "no mailbox", and SIGXFSZ becomes "disk
 * quota exceeded".
 */
# define exc_s_illaddr          12      /* ss$_accvio */
# define exc_s_exquota          28      /* ss$_exquota */
# define exc_s_insfmem          292     /* ss$_insfmem */
# define exc_s_nopriv           36      /* ss$_nopriv */
# define exc_s_normal           1       /* ss$_normal */
# define exc_s_illinstr         1084    /* ss$_opcdec */
# define exc_s_resaddr          1100    /* ss$_radrmod */
# define exc_s_privinst         1084    /* ss$_opcdec */
# define exc_s_resoper          1108    /* ss$_roprand */
# define exc_s_SIGTRAP          1044    /* ss$_break */
# define exc_s_SIGIOT           44      /* ss$_abort */
# define exc_s_SIGEMT           1068    /* ss$_compat */
# define exc_s_aritherr         1164    /* ss$_fltovf */
# define exc_s_SIGSYS           20      /* ss$_badparam */
# define exc_s_SIGPIPE          628     /* ss$_nombx */
# define exc_s_excpu            8364    /* ss$_excputim */
# define exc_s_exfilsiz         1004    /* ss$_exdiskquota */
# define exc_s_intovf           1148    /* ss$_intovf */
# define exc_s_intdiv           1156    /* ss$_intdiv */
# define exc_s_fltovf           1164    /* ss$_fltovf */
# define exc_s_fltdiv           1172    /* ss$_fltdiv */
# define exc_s_fltund           1180    /* ss$_fltund */
# define exc_s_decovf           1188    /* ss$_decovf */
# define exc_s_subrng           1196    /* ss$_subrng */
#else
# define exc_s_illaddr          _EXC_STATUS_(5, 4)
# define exc_s_exquota          _EXC_STATUS_(6, 4)
# define exc_s_insfmem          _EXC_STATUS_(7, 4)
# define exc_s_nopriv           _EXC_STATUS_(8, 4)
# define exc_s_normal           _EXC_STATUS_(9, 1)
# define exc_s_illinstr         _EXC_STATUS_(10, 4)
# define exc_s_resaddr          _EXC_STATUS_(11, 4)
# define exc_s_privinst         _EXC_STATUS_(12, 4)
# define exc_s_resoper          _EXC_STATUS_(13, 4)
# define exc_s_SIGTRAP          _EXC_STATUS_(14, 4)
# define exc_s_SIGIOT           _EXC_STATUS_(15, 4)
# define exc_s_SIGEMT           _EXC_STATUS_(16, 4)
# define exc_s_aritherr         _EXC_STATUS_(17, 4)
# define exc_s_SIGSYS           _EXC_STATUS_(18, 4)
# define exc_s_SIGPIPE          _EXC_STATUS_(19, 4)
# define exc_s_excpu            _EXC_STATUS_(20, 4)
# define exc_s_exfilsiz         _EXC_STATUS_(21, 4)
# define exc_s_intovf           _EXC_STATUS_(22, 4)
# define exc_s_intdiv           _EXC_STATUS_(23, 4)
# define exc_s_fltovf           _EXC_STATUS_(24, 4)
# define exc_s_fltdiv           _EXC_STATUS_(25, 4)
# define exc_s_fltund           _EXC_STATUS_(26, 4)
# define exc_s_decovf           _EXC_STATUS_(27, 4)
# define exc_s_subrng           _EXC_STATUS_(28, 4)
# if (_CMA_UNIX_TYPE == _CMA__SVR4)
#  define exc_s_illopc      _EXC_STATUS_(29, 4)
#  define exc_s_illopn      _EXC_STATUS_(30, 4)
#  define exc_s_illadr      _EXC_STATUS_(31, 4)
#  define exc_s_illtrp      _EXC_STATUS_(32, 4)
#  define exc_s_prvopc      _EXC_STATUS_(33, 4)
#  define exc_s_prvreg      _EXC_STATUS_(34, 4)
#  define exc_s_coproc      _EXC_STATUS_(35, 4)
#  define exc_s_badstk      _EXC_STATUS_(36, 4)
#  define exc_s_brkpt       _EXC_STATUS_(37, 4)
#  define exc_s_trace       _EXC_STATUS_(38, 4)
#  define exc_s_fltinv          _EXC_STATUS_(39, 4)
#  define exc_s_maperr          _EXC_STATUS_(40, 4)
#  define exc_s_accerr          _EXC_STATUS_(41, 4)
#  define exc_s_adraln          _EXC_STATUS_(42, 4)
#  define exc_s_adrerr          _EXC_STATUS_(43, 4)
#  define exc_s_objerr      _EXC_STATUS_(44, 4)
#  define exc_s_fltres      _EXC_STATUS_(45, 4)
# endif /* _CMA_UNIX_TYPE == _CMA__SVR4 */
#endif

/*
 * Define alias names
 */
#define exc_s_accvio            exc_s_illaddr
#define exc_s_SIGILL            exc_s_illinstr
#define exc_s_SIGFPE            exc_s_aritherr
#define exc_s_SIGBUS            exc_s_illaddr
#define exc_s_SIGSEGV           exc_s_illaddr
#define exc_s_SIGXCPU           exc_s_excpu
#define exc_s_SIGXFSZ           exc_s_exfilsiz

/*
 * DECthreads facility (CMA) messages
 */
#define cma_s_alerted           _EXC_STATUS_(48, 4)
#define cma_s_assertion         _EXC_STATUS_(49, 4)
#define cma_s_badparam          _EXC_STATUS_(50, 4)
#define cma_s_bugcheck          _EXC_STATUS_(51, 4)
#define cma_s_exit_thread       _EXC_STATUS_(52, 4)
#define cma_s_existence         _EXC_STATUS_(53, 4)
#define cma_s_in_use            _EXC_STATUS_(54, 4)
#define cma_s_use_error         _EXC_STATUS_(55, 4)
#define cma_s_wrongmutex        _EXC_STATUS_(56, 4)
#define cma_s_stackovf          _EXC_STATUS_(57, 4)
#define cma_s_nostackmem        _EXC_STATUS_(58, 4)
#define cma_s_notcmastack       _EXC_STATUS_(59, 4)
#define cma_s_timed_out         _EXC_STATUS_(60, 4)
#define cma_s_unimp             _EXC_STATUS_(61, 4)
#define cma_s_inialrpro         _EXC_STATUS_(62, 4)
#define cma_s_defer_q_full      _EXC_STATUS_(63, 4)
#define cma_s_signal_q_full     _EXC_STATUS_(64, 4)
#define cma_s_alert_nesting     _EXC_STATUS_(65, 4)

#ifdef IBMOS2
#define exc_s_nopthreadinit     _EXC_STATUS_(4094, 4)
#endif

/*
 * Synonyms for convenience
 */
#define cma_s_normal            exc_s_normal

/*
 * TYPEDEFS
 */

/*
 * Constants for the kind of an exception object.
 *
 * There are *currently* only two kinds.  In the address-kind, the identity
 * of an exception object is its address; in the value-kind, the
 * identity of an exception object is an integer, typically,
 * a system-defined-status-value. These coded kinds also
 * serve as sentinels to help detect uninitialized exceptions.
 */
typedef enum EXC_KIND_T {
    exc_kind_address_c  = 0x02130455,
    exc_kind_status_c   = 0x02130456
    }                   exc_kind_t;

/*
 * Internal contents of an exception object.
 */
typedef long int exc_int_t;

typedef struct EXC_EXT_T {
    exc_int_t           sentinel;
    exc_int_t           version;
    exc_address_t       extend;
    unsigned int        *args;
    } exc_ext_t;

typedef struct EXC_KIND_V1ADDR_T {
    exc_kind_t          kind;
    exc_address_t       address;
    exc_int_t           filler[6];
    } exc_kind_v1addr_t;

typedef struct EXC_KIND_V1STATUS_T {
    exc_kind_t          kind;
    exc_int_t           status;
    exc_int_t           filler[6];
    } exc_kind_v1status_t;

typedef struct EXC_KIND_ADDRESS_T {
    exc_kind_t          kind;
    exc_address_t       address;
    exc_ext_t           ext;
    } exc_kind_address_t;

typedef struct EXC_KIND_STATUS_T {
    exc_kind_t          kind;
    exc_int_t           status;
    exc_ext_t           ext;
    } exc_kind_status_t;

typedef union EXC_EXCEPTION_T   {
    exc_kind_t          kind;
    exc_kind_v1status_t v1status;
    exc_kind_v1addr_t   v1address;
    exc_kind_status_t   status;
    exc_kind_address_t  address;
    } EXCEPTION;

/*
 * Constants for the state of handling in the current TRY clause.
 *
 * The state is "none" when no exception has been raised, "active" when
 * one has been raised but has not yet been caught by a CATCH clause, and
 * "handled" after the exception has been caught by some CATCH clause.
 */
typedef enum EXC_STATE_T {
    exc_active_c        = 0, /* This must be the 0 state, see pop_ctx */
    exc_none_c          = 1,
    exc_handled_c       = 2,
    exc_popped_c        = 3
    }                   exc_state_t;

/*
 * Structure of a context block.
 *
 * A context block is allocated in the current stack frame for each
 * TRY clause.  These context blocks are linked to form a stack of
 * all current TRY blocks in the current thread.  Each context block
 * contains a jump buffer for use by setjmp and longjmp.
 *
 */
#define exc_excargs_c   40

typedef struct EXC_CONTEXT_T {
#ifndef IBMOS2
    cma__t_jmp_buf		jmp;			/* Jump buffer */
#endif	/*	!IBMOS2	*/
    _EXC_VOLATILE_ struct EXC_CONTEXT_T
                        *link;          /* Link to context block stack */
    EXCEPTION           cur_exception;  /* Copy of the current exception */
    exc_state_t         exc_state;      /* State of handling for this TRY */
#if _EXC_OS_ == _EXC__VMS
    exc_address_t       current_frame;  /* Address of current stack frame */
# if _EXC_PLATFORM_ == _EXC__VAX_VMS
    exc_address_t       old_handler;    /* Address of previous handler */
# endif
#endif
    exc_int_t           sentinel;       /* Identify as "new" ctx block */
    exc_int_t           version;        /* Client context version */
#ifdef IBMOS2
    cma__t_jmp_buf		jmp;			/* Jump buffer */
#endif	/*	IBMOS2	*/
    unsigned int        exc_args[exc_excargs_c];
#ifdef IBMOS2
    cma__t_jmp_buf_new  newjmp;            /* Jump buffer */
#endif	/*	IBMOS2	*/
    } exc_context_t;

/*
 *  GLOBAL DATA
 */

#if _EXC_OS_ == _EXC__VMS
/*
 * On VMS, use the VMS calling standard ("$") interface, to avoid pulling in
 * the open interface image (cma$open_rtl) unless the client code uses it.
 */
extern void cma$exc_push_ctx _EXC_PROTOTYPE_ (( /* Push a context block */
        _EXC_VOLATILE_  exc_context_t *cb));
extern void cma$exc_pop_ctx _EXC_PROTOTYPE_ ((  /* Pop a context block */
        _EXC_VOLATILE_  exc_context_t *cb));
extern void cma$exc_raise _EXC_PROTOTYPE_ ((    /* Raise an exception */
        EXCEPTION *exc));
extern void cma$exc_raise_status _EXC_PROTOTYPE_ ((     /* Raise a status as exception*/
        exc_int_t       status));
extern void cma$exc_report _EXC_PROTOTYPE_ ((   /* Report an exception */
        EXCEPTION *exc));
# define exc_push_ctx           cma$exc_push_ctx
# define exc_pop_ctx            cma$exc_pop_ctx
# define exc_raise              cma$exc_raise
# define exc_raise_status       cma$exc_raise_status
# define exc_report             cma$exc_report
#else

#ifdef IBMOS2
extern void DCEAPI exc_push_ctx _EXC_PROTOTYPE_ ((    /* Push a context block */
												  _EXC_VOLATILE_  exc_context_t *cb));
extern void DCEAPI exc_pop_ctx _EXC_PROTOTYPE_ ((      /* Pop a context block */
												 _EXC_VOLATILE_  exc_context_t *cb));
extern void DCEAPI exc_raise _EXC_PROTOTYPE_ ((        /* Raise an exception */
											   EXCEPTION *exc));
extern void DCEAPI exc_raise_status _EXC_PROTOTYPE_ (( /* Raise a status as exception*/
													  exc_int_t       status));
extern void DCEAPI exc_report _EXC_PROTOTYPE_ ((       /* Report an exception */
												EXCEPTION *exc));
#else	/*	!IBMOS2	*/
extern void exc_push_ctx _EXC_PROTOTYPE_ ((	/* Push a context block */
										   _EXC_VOLATILE_	exc_context_t *cb));
extern void exc_pop_ctx _EXC_PROTOTYPE_ ((	/* Pop a context block */
										  _EXC_VOLATILE_	exc_context_t *cb));
extern void exc_raise _EXC_PROTOTYPE_ ((	/* Raise an exception */
										EXCEPTION *exc));
extern void exc_raise_status _EXC_PROTOTYPE_ ((	/* Raise a status as exception*/
											   exc_int_t	status));
extern void exc_report _EXC_PROTOTYPE_ ((	/* Report an exception */
										 EXCEPTION *exc));
#endif	/*	!IBMOS2	*/
#endif

#if _EXC_OS_ == _EXC__VMS
extern int  cma$exc_handler (/* sargs, margs*/);        /* System condition handler */
#endif

/*
 * Define the exception values that go with the above status codes
 *
 * NOTE: it does not make sense to turn all of the above into
 * exceptions as some are never raised as exceptions.  Those are:
 *      cma_s_normal    -- never signalled
 *      cma_s_exception -- internal to the implementation of exceptions
 *      cma_s_exccop    -- internal to the implementation of exceptions
 *      cma_s_timed_out -- returned as status value from timed condition wait
 */

#if !defined (_EXC_NO_EXCEPTIONS_) && !defined (_CMA_SUPPRESS_EXTERNALS_)
#if (defined (IBMOS2) && !(defined(__BORLANDC__)))
/*
 *	__BORLANDC__
 *		appends an "_" to the variable name therfore
 *		all the symbols must be redefined and exported prefaced with an "_"
 */
_EXC_IMPORT_ EXCEPTION
    _exc_e_uninitexc,
    _exc_e_illaddr,
    _exc_e_exquota,
    _exc_e_insfmem,
    _exc_e_nopriv,
    _exc_e_illinstr,
    _exc_e_resaddr,
    _exc_e_privinst,
    _exc_e_resoper,
    _exc_e_SIGTRAP,
    _exc_e_SIGIOT,
    _exc_e_SIGEMT,
    _exc_e_aritherr,
    _exc_e_SIGSYS,
    _exc_e_SIGPIPE,
    _exc_e_excpu,
    _exc_e_exfilsiz,
    _exc_e_intovf,
    _exc_e_intdiv,
    _exc_e_fltovf,
    _exc_e_fltdiv,
    _exc_e_fltund,
    _exc_e_decovf,
    _exc_e_subrng,
    _cma_e_alerted,
    _cma_e_assertion,
    _cma_e_badparam,
    _cma_e_bugcheck,
    _cma_e_exit_thread,
    _cma_e_existence,
    _cma_e_in_use,
    _cma_e_use_error,
    _cma_e_wrongmutex,
    _cma_e_stackovf,
    _cma_e_nostackmem,
    _cma_e_notcmastack,
    _cma_e_unimp,
    _cma_e_inialrpro,
    _cma_e_defer_q_full,
    _cma_e_signal_q_full,
    _cma_e_alert_nesting;

#define exc_e_uninitexc       _exc_e_uninitexc
#define exc_e_illaddr         _exc_e_illaddr
#define exc_e_exquota         _exc_e_exquota
#define exc_e_insfmem         _exc_e_insfmem
#define exc_e_nopriv          _exc_e_nopriv
#define exc_e_illinstr        _exc_e_illinstr
#define exc_e_resaddr         _exc_e_resaddr
#define exc_e_privinst        _exc_e_privinst
#define exc_e_resoper         _exc_e_resoper
#define exc_e_SIGTRAP         _exc_e_SIGTRAP
#define exc_e_SIGIOT          _exc_e_SIGIOT
#define exc_e_SIGEMT          _exc_e_SIGEMT
#define exc_e_aritherr        _exc_e_aritherr
#define exc_e_SIGSYS          _exc_e_SIGSYS
#define exc_e_SIGPIPE         _exc_e_SIGPIPE
#define exc_e_excpu           _exc_e_excpu
#define exc_e_exfilsiz        _exc_e_exfilsiz
#define exc_e_intovf          _exc_e_intovf
#define exc_e_intdiv          _exc_e_intdiv
#define exc_e_fltovf          _exc_e_fltovf
#define exc_e_fltdiv          _exc_e_fltdiv
#define exc_e_fltund          _exc_e_fltund
#define exc_e_decovf          _exc_e_decovf
#define exc_e_subrng          _exc_e_subrng
#define cma_e_alerted         _cma_e_alerted
#define cma_e_assertion       _cma_e_assertion
#define cma_e_badparam        _cma_e_badparam
#define cma_e_bugcheck        _cma_e_bugcheck
#define cma_e_exit_thread     _cma_e_exit_thread
#define cma_e_existence       _cma_e_existence
#define cma_e_in_use          _cma_e_in_use
#define cma_e_use_error       _cma_e_use_error
#define cma_e_wrongmutex      _cma_e_wrongmutex
#define cma_e_stackovf        _cma_e_stackovf
#define cma_e_nostackmem      _cma_e_nostackmem
#define cma_e_notcmastack     _cma_e_notcmastack
#define cma_e_unimp           _cma_e_unimp
#define cma_e_inialrpro       _cma_e_inialrpro
#define cma_e_defer_q_full    _cma_e_defer_q_full
#define cma_e_signal_q_full   _cma_e_signal_q_full
#define cma_e_alert_nesting   _cma_e_alert_nesting
#else	/*	!(IBMOS2 && !__BORLANDC__)	*/
_EXC_IMPORT_ EXCEPTION
    exc_e_uninitexc,
    exc_e_illaddr,
    exc_e_exquota,
    exc_e_insfmem,
    exc_e_nopriv,
    exc_e_illinstr,
    exc_e_resaddr,
    exc_e_privinst,
    exc_e_resoper,
    exc_e_SIGTRAP,
    exc_e_SIGIOT,
    exc_e_SIGEMT,
    exc_e_aritherr,
    exc_e_SIGSYS,
    exc_e_SIGPIPE,
    exc_e_excpu,
    exc_e_exfilsiz,
    exc_e_intovf,
    exc_e_intdiv,
    exc_e_fltovf,
    exc_e_fltdiv,
    exc_e_fltund,
    exc_e_decovf,
    exc_e_subrng,
# if (_CMA_UNIX_TYPE == _CMA__SVR4)
	exc_e_illopc,
	exc_e_illopn,
	exc_e_illadr,
	exc_e_illtrp,
	exc_e_prvopc,
	exc_e_prvreg,
	exc_e_coproc,
	exc_e_badstk,
	exc_e_brkpt,
	exc_e_trace,
	exc_e_objerr,
	exc_e_fltres,
	exc_e_fltinv,
	exc_e_maperr,
	exc_e_accerr,
	exc_e_adraln,
	exc_e_adrerr,
# endif
    cma_e_alerted,
    cma_e_assertion,
    cma_e_badparam,
    cma_e_bugcheck,
    cma_e_exit_thread,
    cma_e_existence,
    cma_e_in_use,
    cma_e_use_error,
    cma_e_wrongmutex,
    cma_e_stackovf,
    cma_e_nostackmem,
    cma_e_notcmastack,
    cma_e_unimp,
    cma_e_inialrpro,
    cma_e_defer_q_full,
    cma_e_signal_q_full,
    cma_e_alert_nesting;
#endif	/*	!(IBMOS2 && !__BORLANDC__)	*/

/*
 * Define aliased exceptions
 */
# define exc_e_accvio           exc_e_illaddr
# define exc_e_SIGILL           exc_e_illinstr
# define exc_e_SIGFPE           exc_e_aritherr
# define exc_e_SIGBUS           exc_e_illaddr
# define exc_e_SIGSEGV          exc_e_illaddr
# define exc_e_SIGXCPU          exc_e_excpu
# define exc_e_SIGXFSZ          exc_e_exfilsiz

/*
 * The following are pthread exception names.
 */

# define exc_uninitexc_e        exc_e_uninitexc
# define exc_illaddr_e          exc_e_illaddr
# define exc_exquota_e          exc_e_exquota
# define exc_insfmem_e          exc_e_insfmem
# define exc_nopriv_e           exc_e_nopriv
# define exc_illinstr_e         exc_e_illinstr
# define exc_resaddr_e          exc_e_resaddr
# define exc_privinst_e         exc_e_privinst
# define exc_resoper_e          exc_e_resoper
# define exc_SIGTRAP_e          exc_e_SIGTRAP
# define exc_SIGIOT_e           exc_e_SIGIOT
# define exc_SIGEMT_e           exc_e_SIGEMT
# define exc_aritherr_e         exc_e_aritherr
# define exc_SIGSYS_e           exc_e_SIGSYS
# define exc_SIGPIPE_e          exc_e_SIGPIPE
# define exc_excpu_e            exc_e_excpu
# define exc_exfilsiz_e         exc_e_exfilsiz
# define exc_intovf_e           exc_e_intovf
# define exc_intdiv_e           exc_e_intdiv
# define exc_fltovf_e           exc_e_fltovf
# define exc_fltdiv_e           exc_e_fltdiv
# define exc_fltund_e           exc_e_fltund
# define exc_decovf_e           exc_e_decovf
# define exc_subrng_e           exc_e_subrng
# if (_CMA_UNIX_TYPE == _CMA__SVR4)
#  define	exc_illopc_e	exc_e_illopc
#  define	exc_illopn_e	exc_e_illopn
#  define	exc_illadr_e	exc_e_illadr
#  define	exc_illtrp_e	exc_e_illtrp
#  define	exc_prvopc_e	exc_e_prvopc
#  define	exc_prvreg_e	exc_e_prvreg
#  define	exc_coproc_e	exc_e_coproc
#  define	exc_badstk_e	exc_e_badstk
#  define	exc_brkpt_e		exc_e_brkpt
#  define	exc_trace_e		exc_e_trace
#  define	exc_objerr_e	exc_e_objerr
#  define	exc_fltres_e	exc_e_fltres
#  define   exc_fltinv_e	exc_e_fltinv
#  define   exc_maperr_e    exc_e_maperr
#  define   exc_accerr_e    exc_e_accerr
#  define   exc_adraln_e    exc_e_adraln
#  define   exc_adrerr_e    exc_e_adrerr
# endif

# define pthread_cancel_e       cma_e_alerted
# define pthread_assertion_e    cma_e_assertion
# define pthread_badparam_e     cma_e_badparam
# define pthread_bugcheck_e     cma_e_bugcheck
# define pthread_exit_thread_e  cma_e_exit_thread
# define pthread_existence_e    cma_e_existence
# define pthread_in_use_e       cma_e_in_use
# define pthread_use_error_e    cma_e_use_error
# define pthread_wrongmutex_e   cma_e_wrongmutex
# define pthread_stackovf_e     cma_e_stackovf
# define pthread_nostackmem_e   cma_e_nostackmem
# define pthread_notstack_e     cma_e_notcmastack
# define pthread_unimp_e        cma_e_unimp
# define pthread_inialrpro_e    cma_e_inialrpro
# define pthread_defer_q_full_e cma_e_defer_q_full
# define pthread_signal_q_full_e cma_e_signal_q_full

# define exc_accvio_e           exc_e_accvio
# define exc_SIGILL_e           exc_e_SIGILL
# define exc_SIGFPE_e           exc_e_SIGFPE
# define exc_SIGBUS_e           exc_e_SIGBUS
# define exc_SIGSEGV_e          exc_e_SIGSEGV
# define exc_SIGXCPU_e          exc_e_SIGXCPU
# define exc_SIGXFSZ_e          exc_e_SIGXFSZ
#endif

/*
 * CONSTANTS AND MACROS
 */

/*
 * This constant helps to identify a context block or exception created with
 * DECthreads BL9 or later; the new structures include a version field to
 * better manage future changes.
 */
#define exc_newexc_c    0x45586732      /* Identify ctx block with version */

/*
 * Define a version constant to be put into exception structures.
 */
#define exc_v2exc_c     2

/*
 * Define "keyword" to initialize an exception. Note: all exceptions *must*
 * be initialized using this macro.
 */
#define EXCEPTION_INIT(e)   (   \
    (e).address.address = (exc_address_t)&(e),  \
    (e).address.kind = exc_kind_address_c, \
    (e).address.ext.sentinel = exc_newexc_c, \
    (e).address.ext.version = exc_v2exc_c, \
    (e).address.ext.extend = (exc_address_t)0, \
    (e).address.ext.args = (unsigned int *)0)

/*
 * Define "routine" to equivalence an exception to an integer
 * (typically a system-defined status value).
 */
#define exc_set_status(e,s) ( \
    (e)->status.status = (s), \
    (e)->status.kind = exc_kind_status_c)

/*
 * Define "routine" to return the status of an exception. Returns 0 if status
 * kind (and value of status in *s), or -1 if not status kind.
 */
#define exc_get_status(e,s) ( \
    (e)->kind == exc_kind_status_c ? \
        (*(s) = (e)->status.status, 0) : \
        -1)

/*
 * Define "routine" to determine if two exceptions match.
 */
#define exc_matches(e1,e2) \
    ((e1)->kind == (e2)->kind \
    && (e1)->address.address == (e2)->address.address)

/*
 * Define "statement" for clients to use to raise an exception.
 */
#define RAISE(e) exc_raise(&(e))

#if _EXC_PLATFORM_ == _EXC__VAX_VMS
/*
 * For VAX VMS, try to integrate peacefully with native VMS condition
 * handling. Save the previous handler for the frame, and restore it on
 * ENDTRY. The DECthreads condition handler will call the saved handler
 * before resignalling a condition that we don't want to handle, unless
 * it is the DECthreads condition handler (to avoid infinite recursion).
 */
# define exc_establish(_exc_ctx_) ( \
        (_exc_ctx_)->current_frame = ((exc_address_t)cma$exc_fetch_fp()), \
        (_exc_ctx_)->old_handler = \
                *((exc_address_t *)(_exc_ctx_)->current_frame), \
        *(exc_address_t *)(_exc_ctx_)->current_frame = \
                ((exc_address_t)cma$exc_handler))

# define exc_unestablish(_exc_ctx_) \
        *(exc_address_t *)(_exc_ctx_)->current_frame = (_exc_ctx_)->old_handler;
#else
# if _EXC_PLATFORM_ == _EXC__ALPHA_VMS
    /*
     * Workaround: early Alpha DEC C baselevels require including the header
     * file vaxcshr.h to direct C RTL calls to the proper DEC C entry points.
     * This header erroneously defines "vaxc$establish" to "decc$establish",
     * which doesn't exist and isn't properly translated into defining a
     * condition handler in the procedure descriptor. So defeat the #define
     * manually.
     */
#ifdef IBMOS2
/*
 *	Comment out the three lines below to support WATCOM C++, whose
 *	breaks with the '$'
 */
/*
#endif
#  ifdef vaxc$establish
#   undef vaxc$establish
#  endif
#ifdef IBMOS2
*/
#endif	/*	!IBMOS2	*/

#  define exc_establish(_exc_ctx_) \
        (_exc_ctx_)->current_frame = ((exc_address_t)cma$exc_fetch_fp()); \
        lib$establish (cma$exc_handler);
#  define exc_unestablish(_exc_ctx_)
# else
#  define exc_establish(_exc_ctx_)
#  define exc_unestablish(_exc_ctx_)
# endif
#endif

/*
 * Constants to define versions of the context block:
 */
#define exc_v2ctx_c     2

#ifdef __hpux
#define _exc_jmpbuf_type double
#else
#define _exc_jmpbuf_type int
#endif

/*
 * Start a new TRY block, which may contain exception handlers
 *
 *   Allocate a context block on the stack to remember the current
 *   exception. Push it on the context block stack.  Initialize
 *   this context block to indicate that no exception is active. Do a SETJMP
 *   to snapshot this environment (or return to it).  Then, start
 *   a block of statements to be guarded by the TRY clause.
 *   This block will be ended by one of the following: a CATCH, CATCH_ALL,
 *   or the ENDTRY macros.
 */
#if (defined(__IBMC__) || defined(__IBMCPP__) )  && !defined(_IBMOS2_DCE_NOFLOAT)
#define TRY \
    { \
        _EXC_VOLATILE_ exc_context_t exc_ctx; \
        exc_ctx.sentinel = exc_newexc_c; \
        exc_ctx.version = exc_v2ctx_c; \
        exc_ctx.exc_args[0] = 0; \
        exc_push_ctx (&exc_ctx);\
        exc_establish (&exc_ctx);\
        if (!exc_setjmp ((_exc_jmpbuf_type *)exc_ctx.jmp)) {
/*              { user's block of code goes here }      */
#else    /* Compiler save go here   */
#define TRY \
    { \
        _EXC_VOLATILE_ exc_context_t exc_ctx; \
        exc_ctx.sentinel = exc_newexc_c; \
        exc_ctx.version = exc_v2ctx_c; \
        exc_ctx.exc_args[0] = 0; \
        exc_push_ctx (&exc_ctx);\
        exc_establish (&exc_ctx);\
        exc_ctx.jmp[2]=0;\
        if (!exc_setjmp (exc_ctx.newjmp)) {
/*              { user's block of code goes here }      */
#endif

/*
 * Define an CATCH(e) clause (or exception handler).
 *
 *   First, end the prior block.  Then, check if the current exception
 *   matches what the user is trying to catch with the CATCH clause.
 *   If there is a match, a variable is declared to support lexical
 *   nesting of RERAISE statements, and the state of the current
 *   exception is changed to "handled".
 */
#define CATCH(e)																\
            }																	\
            else if (exc_matches(&exc_ctx.cur_exception, &(e))) {				\
                EXCEPTION *THIS_CATCH = (EXCEPTION *)&exc_ctx.cur_exception;	\
                exc_ctx.cur_exception = *THIS_CATCH;							\
                exc_ctx.exc_state = exc_handled_c;
/*              { user's block of code goes here }      */

/*
 * Define an CATCH_ALL clause (or "catchall" handler).
 *
 *   First, end the prior block.  Then, unconditionally,
 *   let execution enter into the catchall code.  As with a normal
 *   catch, a variable is declared to support lexical
 *   nesting of RERAISE statements, and the state of the current
 *   exception is changed to "handled".
 */
#define CATCH_ALL																\
            }																	\
            else {																\
                EXCEPTION *THIS_CATCH = (EXCEPTION *)&exc_ctx.cur_exception;	\
                exc_ctx.cur_exception = *THIS_CATCH ;							\
                exc_ctx.exc_state = exc_handled_c;
/*              { user's block of code goes here }      */

/*
 * Define a RERAISE statement.
 *
 *   This "statement" is valid only if lexically nested in
 *   a CATCH or CATCH_ALL clause. Reraise the current lexically visible
 *   exception.
 */
#define RERAISE exc_raise(THIS_CATCH)

/*
 * Define a FINALLY clause
 *
 *   This "keyword" starts a FINALLY clause.  It must appear before
 *   an ENDTRY.  A FINALLY clause will be entered after normal exit
 *   of the TRY block, or if an unhandled exception tries to propagate
 *   out of the TRY block.
 *
 *   Unlike Modula 3's TRY clause, we do not expend overhead trying to
 *   enforce that FINALLY be mutually exclusive with CATCH clauses.  Currently,
 *   if they are used together, then control will drop into a FINALLY clause
 *   under the following conditions:
 *      o normal exit from TRY,
 *      o an exception is raised and no CATCH is present (recommended usage)
 *      o CATCH's are present but none matches the exception.
 *      o CATCH's are present and one matches the exception, but it
 *        does not raise any exception.
 *   That is, FINALLY is always entered after TRY unless a CATCH clause raises
 *   (or re-raises) an exception.
 *
 *                      ** WARNING **
 *   You should *avoid* using FINALLY with CATCH clauses, that is, use it
 *   only as TRY {} FINALLY {} ENDTRY.  Source code that combines CATCHes
 *   with FINALLY in the same TRY clause is considered "unsupported"
 *   -- that is, such code may be broken by a future version of this
 *   package.
 *
 *   There are several reasons this restriction is necessary:
 *      o FINALLY may be added to C++ and its combination with CATCH
 *        clauses may have different semantics than implemented by these macros.
 *      o The restriction is consistant with the same restriction in Modula 3
 *      o It allows the use of the 2-phase or "debugging" implementation
 *        technique of the SRC exception package for these same macros.
 */
#define FINALLY   } \
        if (exc_ctx.exc_state == exc_none_c) \
            exc_pop_ctx (&exc_ctx);\
        {
/*              { user's block of code goes here }      */

/*
 * End the whole TRY clause
 */
#define ENDTRY \
        } \
    exc_unestablish (&exc_ctx); \
    if (exc_ctx.exc_state == exc_none_c \
            || exc_ctx.exc_state == exc_active_c) { \
        exc_pop_ctx (&exc_ctx); \
        } \
    }

#if (_EXC_OS_ == _EXC__VMS) && (_EXC_HARDWARE_ == _EXC__VAX) && (_EXC_COMPILER_ == _EXC__DECCPLUS)
# pragma __extern_model __restore
#endif

#endif
