This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
patch up egcs-1.1.2-mingw32 build (builds a working miniperl, but not
[perl5.git] / perl.h
diff --git a/perl.h b/perl.h
index b8f9ae6..b8d0dd8 100644 (file)
--- a/perl.h
+++ b/perl.h
 #define VOIDUSED 1
 #include "config.h"
 
-/* XXXXXX testing threads via implicit pointer */
+/* See L<perlguts/"The Perl API"> for detailed notes on
+ * PERL_IMPLICIT_CONTEXT and PERL_IMPLICIT_SYS */
+
 #ifdef USE_THREADS
 #  ifndef PERL_IMPLICIT_CONTEXT
 #    define PERL_IMPLICIT_CONTEXT
 #  endif
 #  ifndef PERL_IMPLICIT_SYS
-/*#    define PERL_IMPLICIT_SYS*/              /* XXX not done yet */
+#    if defined(WIN32) && !defined(__MINGW32__)
+#      define PERL_IMPLICIT_SYS                /* XXX not implemented everywhere yet */
+#    endif
 #  endif
 #endif
 
-/* XXXXXX testing multiplicity via implicit pointer */
 #if defined(MULTIPLICITY)
 #  ifndef PERL_IMPLICIT_CONTEXT
 #    define PERL_IMPLICIT_CONTEXT
 #  endif
 #  ifndef PERL_IMPLICIT_SYS
-/*#    define PERL_IMPLICIT_SYS*/              /* XXX not done yet */
+#    if defined(WIN32) && !defined(__MINGW32__)
+#      define PERL_IMPLICIT_SYS                /* XXX not implemented everywhere yet */
+#    endif
 #  endif
 #endif
 
@@ -85,8 +90,8 @@ the perl interpreter.
 | Perl Host |
 +-----------+
       ^
-         |
-         v
+      |
+      v
 +-----------+   +-----------+
 | Perl Core |<->| Extension |
 +-----------+   +-----------+ ...
@@ -145,22 +150,17 @@ class CPerlObj;
 
 #define pTHXo                  CPerlObj *pPerl
 #define pTHXo_                 pTHXo,
-#define _pTHXo                 ,pTHXo
 #define aTHXo                  this
 #define aTHXo_                 this,
-#define _aTHXo                 ,this
 #define PERL_OBJECT_THIS       aTHXo
 #define PERL_OBJECT_THIS_      aTHXo_
-#define _PERL_OBJECT_THIS      _aTHXo
-#define dTHXoa(a)              pTHXo = (CPerlObj *)a
-#define dTHXo                  dTHXoa(PERL_GET_INTERP)
+#define dTHXoa(a)              pTHXo = a
+#define dTHXo                  dTHXoa(PERL_GET_THX)
 
 #define pTHXx          void
 #define pTHXx_
-#define _pTHXx
 #define aTHXx
 #define aTHXx_
-#define _aTHXx
 
 #else /* !PERL_OBJECT */
 
@@ -169,20 +169,18 @@ class CPerlObj;
 struct perl_thread;
 #    define pTHX       register struct perl_thread *thr
 #    define aTHX       thr
-#    define dTHXa(a)   pTHX = (struct perl_thread *)a
-#    define dTHX       dTHXa(THR)
 #    define dTHR       dNOOP
 #  else
-#    define MULTIPLICITY
+#    ifndef MULTIPLICITY
+#      define MULTIPLICITY
+#    endif
 #    define pTHX       register PerlInterpreter *my_perl
 #    define aTHX       my_perl
-#    define dTHXa(a)   pTHX = (PerlInterpreter *)a
-#    define dTHX       dTHXa(PERL_GET_INTERP)
 #  endif
+#  define dTHXa(a)     pTHX = a
+#  define dTHX         dTHXa(PERL_GET_THX)
 #  define pTHX_                pTHX,
-#  define _pTHX                ,pTHX
 #  define aTHX_                aTHX,
-#  define _aTHX                ,aTHX
 #endif
 
 #define STATIC static
@@ -211,10 +209,8 @@ struct perl_thread;
 #ifndef pTHX
 #  define pTHX         void
 #  define pTHX_
-#  define _pTHX
 #  define aTHX
 #  define aTHX_
-#  define _aTHX
 #  define dTHXa(a)     dNOOP
 #  define dTHX         dNOOP
 #endif
@@ -222,20 +218,16 @@ struct perl_thread;
 #ifndef pTHXo
 #  define pTHXo                pTHX
 #  define pTHXo_       pTHX_
-#  define _pTHXo       _pTHX
 #  define aTHXo                aTHX
 #  define aTHXo_       aTHX_
-#  define _aTHXo       _aTHX
 #  define dTHXo                dTHX
 #endif
 
 #ifndef pTHXx
 #  define pTHXx                register PerlInterpreter *my_perl
 #  define pTHXx_       pTHXx,
-#  define _pTHXx       ,pTHXx
 #  define aTHXx                my_perl
 #  define aTHXx_       aTHXx,
-#  define _aTHXx       ,aTHXx
 #  define dTHXx                dTHX
 #endif
 
@@ -328,7 +320,7 @@ register struct op *Perl_op asm(stringify(OP_IN_REGISTER));
 # define STANDARD_C 1
 #endif
 
-#if defined(__cplusplus) || defined(WIN32) || defined(__sgi) || defined(OS2) || defined(__DGUX) || defined( EPOC)
+#if defined(__cplusplus) || defined(WIN32) || defined(__sgi) || defined(OS2) || defined(__DGUX) || defined( EPOC) || defined(__QNX__)
 # define DONT_DECLARE_STD 1
 #endif
 
@@ -401,7 +393,7 @@ register struct op *Perl_op asm(stringify(OP_IN_REGISTER));
 /* HP-UX 10.X CMA (Common Multithreaded Architecure) insists that
    pthread.h must be included before all other header files.
 */
-#if defined(USE_THREADS) && defined(PTHREAD_H_FIRST)
+#if defined(USE_THREADS) && defined(PTHREAD_H_FIRST) && defined(I_PTHREAD)
 #  include <pthread.h>
 #endif
 
@@ -502,10 +494,12 @@ register struct op *Perl_op asm(stringify(OP_IN_REGISTER));
 
 #ifdef MYMALLOC
 #  ifdef PERL_POLLUTE_MALLOC
+#   ifndef PERL_EXTMALLOC_DEF
 #    define Perl_malloc                malloc
 #    define Perl_calloc                calloc
 #    define Perl_realloc       realloc
 #    define Perl_mfree         free
+#   endif
 #  else
 #    define EMBEDMYMALLOC      /* for compatibility */
 #  endif
@@ -694,16 +688,16 @@ Free_t   Perl_mfree (Malloc_t where);
 
 #ifdef USE_THREADS
 #  define ERRSV (thr->errsv)
-#  define ERRHV (thr->errhv)
 #  define DEFSV THREADSV(0)
 #  define SAVE_DEFSV save_threadsv(0)
 #else
 #  define ERRSV GvSV(PL_errgv)
-#  define ERRHV GvHV(PL_errgv)
 #  define DEFSV GvSV(PL_defgv)
 #  define SAVE_DEFSV SAVESPTR(GvSV(PL_defgv))
 #endif /* USE_THREADS */
 
+#define ERRHV GvHV(PL_errgv)   /* XXX unused, here for compatibility */
+
 #ifndef errno
        extern int errno;     /* ANSI allows errno to be an lvalue expr.
                               * For example in multithreaded environments
@@ -901,21 +895,14 @@ Free_t   Perl_mfree (Malloc_t where);
 #include <inttypes.h>
 #endif
 
-/*  XXX QUAD stuff is not currently supported on most systems.
-    Specifically, perl internals don't support long long.  Among
-    the many problems is that some compilers support long long,
-    but the underlying library functions (such as sprintf) don't.
-    Some things do work (such as quad pack/unpack on convex);
-    also some systems use long long for the fpos_t typedef.  That
-    seems to work too.
-
+/*
     The IV type is supposed to be long enough to hold any integral
     value or a pointer.
     --Andy Dougherty   August 1996
 */
 
-/*  Much more 64-bit probing added.  Now we should get Quad_t
-    in most systems: int64_t, long long, long, int, will do.
+/*  We should be able to get Quad_t in most systems:
+    all of int64_t, long long, long, int, will work.
 
     Beware of LP32 systems (ILP32, ILP32LL64).  Such systems have been
     used to sizeof(long) == sizeof(foo*).  This is a bad assumption
@@ -927,9 +914,11 @@ Free_t   Perl_mfree (Malloc_t where);
     Summary: a long long system needs to add -DUSE_LONG_LONG to $ccflags
     to get quads -- and if its pointers are still 32 bits, this will break
     binary compatibility.  Casting an IV (a long long) to a pointer will
-    truncate half of the IV away.
+    truncate half of the IV away.  Most systems can just use
+    Configure -Duse64bits to get the -DUSE_LONG_LONG added either by
+    their hints files, or directly by Configure if they are using gcc.
 
-    --jhi              September 1998 */
+    --jhi              September 1999 */
 
 #if INTSIZE == 4 && LONGSIZE == 4 && PTRSIZE == 4
 #   define PERL_ILP32
@@ -1013,6 +1002,9 @@ Free_t   Perl_mfree (Malloc_t where);
 #    define IV_MAX INT64_MAX
 #    define IV_MIN INT64_MIN
 #    define UV_MAX UINT64_MAX
+#    ifndef UINT64_MIN
+#      define UINT64_MIN 0
+#    endif
 #    define UV_MIN UINT64_MIN
 #  else
 #    define IV_MAX PERL_QUAD_MAX
@@ -1020,13 +1012,24 @@ Free_t   Perl_mfree (Malloc_t where);
 #    define UV_MAX PERL_UQUAD_MAX
 #    define UV_MIN PERL_UQUAD_MIN
 #  endif
+#  define IVSIZE 8
+#  define UVSIZE 8
+#  define IV_IS_QUAD
+#  define UV_IS_QUAD
 #else
    typedef          long               IV;
    typedef         unsigned long      UV;
 #  if defined(INT32_MAX) && LONGSIZE == 4
 #    define IV_MAX INT32_MAX
 #    define IV_MIN INT32_MIN
-#    define UV_MAX UINT32_MAX
+#    ifndef UINT32_MAX_BROKEN /* e.g. HP-UX with gcc messes this up */
+#        define UV_MAX UINT32_MAX
+#    else
+#        define UV_MAX 4294967295U
+#    endif
+#    ifndef UINT32_MIN
+#      define UINT32_MIN 0
+#    endif
 #    define UV_MIN UINT32_MIN
 #  else
 #    define IV_MAX PERL_LONG_MAX
@@ -1034,17 +1037,118 @@ Free_t   Perl_mfree (Malloc_t where);
 #    define UV_MAX PERL_ULONG_MAX
 #    define UV_MIN PERL_ULONG_MIN
 #  endif
+#  if LONGSIZE == 8
+#    define IV_IS_QUAD
+#    define UV_IS_QUAD
+#  else
+#    undef IV_IS_QUAD
+#    undef UV_IS_QUAD
+#  endif
+#  define UVSIZE LONGSIZE
+#  define IVSIZE LONGSIZE
 #endif
+#define IV_DIG (BIT_DIGITS(IVSIZE * 8))
+#define UV_DIG (BIT_DIGITS(UVSIZE * 8))
 
+/*   
+ *  The macros INT2PTR and NUM2PTR are (despite their names)
+ *  bi-directional: they will convert int/float to or from pointers.
+ *  However the conversion to int/float are named explicitly:
+ *  PTR2IV, PTR2UV, PTR2NV.
+ *
+ *  For int conversions we do not need two casts if pointers are
+ *  the same size as IV and UV.   Otherwise we need an explicit
+ *  cast (PTRV) to avoid compiler warnings.
+ */
+#if (IVSIZE == PTRSIZE) && (UVSIZE == PTRSIZE)
+#  define PTRV                 UV
+#  define INT2PTR(any,d)       (any)(d)
+#else
+#  if PTRSIZE == LONGSIZE 
+#    define PTRV               unsigned long
+#  else
+#    define PTRV               unsigned
+#  endif
+#  define INT2PTR(any,d)       (any)(PTRV)(d)
+#endif
+#define NUM2PTR(any,d) (any)(PTRV)(d)
+#define PTR2IV(p)      INT2PTR(IV,p)
+#define PTR2UV(p)      INT2PTR(UV,p)
+#define PTR2NV(p)      NUM2PTR(NV,p)
+  
 #ifdef USE_LONG_DOUBLE
 #  if defined(HAS_LONG_DOUBLE) && (LONG_DOUBLESIZE > DOUBLESIZE)
 #    define LDoub_t long double
+#  else
+#     undef USE_LONG_DOUBLE /* Ouch! */
 #  endif
 #endif
 
+#ifdef OVR_DBL_DIG
+/* Use an overridden DBL_DIG */
+# ifdef DBL_DIG
+#  undef DBL_DIG
+# endif
+# define DBL_DIG OVR_DBL_DIG
+#else
+/* The following is all to get DBL_DIG, in order to pick a nice
+   default value for printing floating point numbers in Gconvert.
+   (see config.h)
+*/
+#ifdef I_LIMITS
+#include <limits.h>
+#endif
+#ifdef I_FLOAT
+#include <float.h>
+#endif
+#ifndef HAS_DBL_DIG
+#define DBL_DIG        15   /* A guess that works lots of places */
+#endif
+#endif
+#ifdef I_FLOAT
+#include <float.h>
+#endif
+#ifndef HAS_DBL_DIG
+#define DBL_DIG        15   /* A guess that works lots of places */
+#endif
+
+#ifdef OVR_LDBL_DIG
+/* Use an overridden LDBL_DIG */
+# ifdef LDBL_DIG
+#  undef LDBL_DIG
+# endif
+# define LDBL_DIG OVR_LDBL_DIG
+#else
+/* The following is all to get LDBL_DIG, in order to pick a nice
+   default value for printing floating point numbers in Gconvert.
+   (see config.h)
+*/
+#ifdef I_LIMITS
+#include <limits.h>
+#endif
+#ifdef I_FLOAT
+#include <float.h>
+#endif
+#ifndef HAS_LDBL_DIG
+#if LONG_DOUBLESIZE == 10
+#define LDBL_DIG 18 /* assume IEEE */
+#else
+#if LONG_DOUBLESIZE == 16
+#define LDBL_DIG 33 /* assume IEEE */
+#else
+#if LONG_DOUBLESIZE == DOUBLESIZE
+#define LDBL_DIG DBL_DIG /* bummer */
+#endif
+#endif
+#endif
+#endif
+#endif
+
 #ifdef USE_LONG_DOUBLE
 #   define HAS_LDOUB
     typedef LDoub_t NV;
+#   define NVSIZE LONG_DOUBLESIZE
+#   define NV_DIG LDBL_DIG
 #   define Perl_modf modfl
 #   define Perl_frexp frexpl
 #   define Perl_cos cosl
@@ -1055,10 +1159,11 @@ Free_t   Perl_mfree (Malloc_t where);
 #   define Perl_atan2 atan2l
 #   define Perl_pow powl
 #   define Perl_floor floorl
-#   define Perl_atof atof
 #   define Perl_fmod fmodl
 #else
     typedef double NV;
+#   define NVSIZE DOUBLESIZE
+#   define NV_DIG DBL_DIG
 #   define Perl_modf modf
 #   define Perl_frexp frexp
 #   define Perl_cos cos
@@ -1069,10 +1174,15 @@ Free_t   Perl_mfree (Malloc_t where);
 #   define Perl_atan2 atan2
 #   define Perl_pow pow
 #   define Perl_floor floor
-#   define Perl_atof atof              /* At some point there may be an atolf */
 #   define Perl_fmod fmod
 #endif
 
+#if defined(USE_LONG_DOUBLE) && defined(HAS_LONG_DOUBLE) && defined(HAS_ATOLF)
+#   define Perl_atof atolf
+#else
+#   define Perl_atof atof
+#endif
+
 /* Previously these definitions used hardcoded figures. 
  * It is hoped these formula are more portable, although
  * no data one way or another is presently known to me.
@@ -1282,9 +1392,6 @@ typedef struct loop LOOP;
 
 typedef struct Outrec Outrec;
 typedef struct interpreter PerlInterpreter;
-#ifndef __BORLANDC__
-typedef struct ff FF;          /* XXX not defined anywhere, should go? */
-#endif
 typedef struct sv SV;
 typedef struct av AV;
 typedef struct hv HV;
@@ -1316,126 +1423,107 @@ typedef union any ANY;
 
 #include "handy.h"
 
-/* Some day when we have more 64-bit experience under our belts we may
- * be able to merge some of the USE_64_BIT_{FILES,OFFSETS,STDIO,DBM}. At
- * the moment (Oct 1998), though, keep them separate. --jhi
- */
-#ifdef USE_64_BITS
-#   ifdef USE_64_BIT_FILES
-#       ifndef USE_64_BIT_OFFSETS
-#          define USE_64_BIT_OFFSETS
-#       endif
-#       ifndef USE_64_BIT_STDIO
-#           define USE_64_BIT_STDIO
-#       endif
-#       ifndef USE_64_BIT_DBM
-#           define USE_64_BIT_DBM
-#       endif
+#if defined(USE_LARGE_FILES)
+#   define USE_64_BIT_RAWIO /* Explicit */
+#   define USE_64_BIT_STDIO
+#endif
+
+#if LSEEKSIZE == 8 && !defined(USE_64_BIT_RAWIO)
+#   define USE_64_BIT_RAWIO /* Implicit */
+#endif
+
+/* Do we need FSEEKSIZE? */
+
+/* I couldn't find any -Ddefine or -flags in IRIX 6.5 that would
+ * have done the necessary symbol renaming using cpp. --jhi */
+#ifdef __sgi
+#define USE_FOPEN64
+#define USE_FSEEK64
+#define USE_FTELL64
+#define USE_FSETPOS64
+#define USE_FGETPOS64
+#define USE_TMPFILE64
+#define USE_FREOPEN64
+#endif
+
+#ifdef USE_64_BIT_RAWIO
+#   ifdef HAS_OFF64_T
+#       undef Off_t
+#       define Off_t off64_t
+#       undef LSEEKSIZE
+#       define LSEEKSIZE 8
 #   endif
-/* Mention LSEEKSIZE here to get it included in %Config. */
-#   ifdef USE_64_BIT_OFFSETS
-#       ifdef HAS_FSTAT64
-#           define fstat fstat64
-#       endif
-#       ifdef HAS_FTRUNCATE64
-#           define ftruncate ftruncate64
-#       endif
-#       ifdef HAS_LSEEK64
-#           define lseek lseek64
-#           ifdef HAS_OFF64_T
-#               undef Off_t
-#               define Off_t off64_t
-#           endif
-#       endif
-#       ifdef HAS_LSTAT64
-#           define lstat lstat64
-#       endif
-       /* Some systems have open64() in libc but use that only
-        * for true LP64 mode, in mixed mode (ILP32LL64, for example)
-        * they use the vanilla open().  Such systems should undefine
-        * d_open64 in their hints files. --jhi */
-#       if defined(HAS_OPEN64)
-#           define open open64
-#       endif
-#       ifdef HAS_OPENDIR64
-#           define opendir opendir64
-#       endif
-#       ifdef HAS_READDIR64
-#           define readdir readdir64
-#          ifdef HAS_STRUCT_DIRENT64
-#               define dirent dirent64
-#           endif
-#       endif
-#       ifdef HAS_SEEKDIR64
-#           define seekdir seekdir64
-#       endif
-#       ifdef HAS_STAT64
-#           define stat stat64 /* Affects also struct stat, hopefully okay. */
-#       endif
-#       ifdef HAS_TELLDIR64
-#           define telldir telldir64
-#       endif
-#       ifdef HAS_TRUNCATE64
-#           define truncate truncate64
-#       endif
-        /* flock is not #defined here to be flock64 because it seems
-          that a system may have struct flock64 but still use flock()
-          and not flock64().  The actual flocking code in pp_sys.c
-          must be changed.  Also lockf and lockf64 must be dealt
-          with in pp_sys.c. --jhi */
-#   endif
-#   ifdef USE_64_BIT_STDIO
-#       ifdef HAS_FGETPOS64
-#           define fgetpos fgetpos64
-#       endif
-#       ifdef HAS_FOPEN64
-#           define fopen fopen64
-#       endif
-#       ifdef HAS_FREOPEN64
-#           define freopen freopen64
-#       endif
-#       ifdef HAS_FSEEK64
-#           define fseek fseek64
-#       endif
-#       ifdef HAS_FSEEKO64
-#           define fseeko fseeko64
-#       endif
-#       ifdef HAS_FSETPOS64
-#           define fsetpos fsetpos64
-#       endif
-#       ifdef HAS_FTELL64
-#           define ftell ftell64
-#       endif
-#       ifdef HAS_FTELLO64
-#           define ftello ftello64
-#       endif
-#       ifdef HAS_TMPFILE64
-#           define tmpfile tmpfile64
-#       endif
+/* Most 64-bit environments have defines like _LARGEFILE_SOURCE that
+ * will trigger defines like the ones below.  Some 64-bit environments,
+ * however, do not.  Therefore we have to explicitly mix and match. */
+#   if defined(USE_OPEN64)
+#       define open open64
 #   endif
-#   ifdef USE_64_BIT_DBM
-#       ifdef HAS_DBMINIT64
-#           define dbminit dbminit64
-#       endif
-#       ifdef HAS_DBMCLOSE64
-#           define dbmclose dbmclose64
-#       endif
-#       ifdef HAS_FETCH64
-#           define fetch fetch64
-#       endif
-#       ifdef HAS_DELETE64
-#           define delete delete64
-#       endif
-#       ifdef HAS_STORE64
-#           define store store64
-#       endif
-#       ifdef HAS_FIRSTKEY64
-#           define firstkey firstkey64
-#       endif
-#       ifdef HAS_NEXTKEY64
-#           define nextkey nextkey64
-#       endif
+#   if defined(USE_LSEEK64)
+#       define lseek lseek64
+#   endif
+#   if defined(USE_LLSEEK)
+#       define lseek llseek
+#   endif
+#   if defined(USE_STAT64)
+#       define stat stat64
+#   endif
+#   if defined(USE_FSTAT64)
+#       define fstat fstat64
+#   endif
+#   if defined(USE_LSTAT64)
+#       define lstat lstat64
+#   endif
+#   if defined(USE_FLOCK64)
+#       define flock flock64
+#   endif
+#   if defined(USE_LOCKF64)
+#       define lockf lockf64
+#   endif
+#   if defined(USE_FCNTL64)
+#       define fcntl fcntl64
+#   endif
+#   if defined(USE_TRUNCATE64)
+#       define truncate truncate64
+#   endif
+#   if defined(USE_FTRUNCATE64)
+#       define ftruncate ftruncate64
+#   endif
+#endif
+
+#ifdef USE_64_BIT_STDIO
+#   ifdef HAS_FPOS64_T
+#       undef Fpos_t
+#       define Fpos_t fpos64_t
+#   endif
+/* Most 64-bit environments have defines like _LARGEFILE_SOURCE that
+ * will trigger defines like the ones below.  Some 64-bit environments,
+ * however, do not. */
+#   if defined(USE_FOPEN64)
+#       define fopen fopen64
+#   endif
+#   if defined(USE_FSEEK64)
+#       define fseek fseek64
+#   endif
+#   if defined(USE_FTELL64)
+#       define ftell ftell64
 #   endif
+#   if defined(USE_FSETPOS64)
+#       define fsetpos fsetpos64
+#   endif
+#   if defined(USE_FGETPOS64)
+#       define fgetpos fgetpos64
+#   endif
+#   if defined(USE_TMPFILE64)
+#       define tmpfile tmpfile64
+#   endif
+#   if defined(USE_FREOPEN64)
+#       define freopen freopen64
+#   endif
+#endif
+
+#if defined(OS2)
+#  include "iperlsys.h"
 #endif
 
 #if defined(__OPEN_VM)
@@ -1472,6 +1560,10 @@ typedef union any ANY;
 # endif
 #endif         
 
+#ifndef PERL_SYS_INIT3
+#  define PERL_SYS_INIT3(argvp,argcp,envp) PERL_SYS_INIT(argvp,argcp)
+#endif
+
 #ifndef MAXPATHLEN
 #  ifdef PATH_MAX
 #    ifdef _POSIX_PATH_MAX
@@ -1525,7 +1617,9 @@ typedef mutex_t           perl_mutex;
 typedef condition_t    perl_cond;
 typedef void *         perl_key;
 #        else /* Posix threads */
-#          include <pthread.h>
+#          ifdef I_PTHREAD
+#            include <pthread.h>
+#          endif
 typedef pthread_t      perl_os_thread;
 typedef pthread_mutex_t        perl_mutex;
 typedef pthread_cond_t perl_cond;
@@ -1595,7 +1689,6 @@ typedef pthread_key_t     perl_key;
 
 /* This defines a way to flush all output buffers.  This may be a
  * performance issue, so we allow people to disable it.
- * XXX the default needs a Configure test, as it may not work everywhere.
  */
 #ifndef PERL_FLUSHALL_FOR_CHILD
 # if defined(FFLUSH_NULL) || defined(USE_SFIO)
@@ -1609,6 +1702,10 @@ typedef pthread_key_t    perl_key;
 # endif
 #endif
 
+/* the traditional thread-unsafe notion of "current interpreter".
+ * XXX todo: a thread-safe version that fetches it from TLS (akin to THR)
+ * needs to be defined elsewhere (conditional on pthread_getspecific()
+ * availability). */
 #ifndef PERL_SET_INTERP
 #  define PERL_SET_INTERP(i)           (PL_curinterp = (PerlInterpreter*)(i))
 #endif
@@ -1617,6 +1714,22 @@ typedef pthread_key_t    perl_key;
 #  define PERL_GET_INTERP              (PL_curinterp)
 #endif
 
+#if defined(PERL_IMPLICIT_CONTEXT) && !defined(PERL_GET_THX)
+#  ifdef USE_THREADS
+#    define PERL_GET_THX               THR
+#  else
+#  ifdef MULTIPLICITY
+#    define PERL_GET_THX               PERL_GET_INTERP
+#  else
+#  ifdef PERL_OBJECT
+#    define PERL_GET_THX               ((CPerlObj*)PERL_GET_INTERP)
+#  else
+#    define PERL_GET_THX               ((void*)0)
+#  endif
+#  endif
+#  endif
+#endif
+
 /* Some unistd.h's give a prototype for pause() even though
    HAS_PAUSE ends up undefined.  This causes the #define
    below to be rejected by the compmiler.  Sigh.
@@ -1637,7 +1750,7 @@ typedef pthread_key_t     perl_key;
 #   endif
 #endif
 
-#if defined(CYGWIN32)
+#if defined(CYGWIN)
 /* USEMYBINMODE
  *   This symbol, if defined, indicates that the program should
  *   use the routine my_binmode(FILE *fp, char iotype) to insure
@@ -1646,7 +1759,7 @@ typedef pthread_key_t     perl_key;
  */
 #  define USEMYBINMODE / **/
 #  define my_binmode(fp, iotype) \
-            (PerlLIO_setmode(PerlIO_fileno(fp), O_BINARY) != -1 ? TRUE : NULL)
+            (PerlLIO_setmode(PerlIO_fileno(fp), O_BINARY) != -1 ? TRUE : FALSE)
 #endif
 
 #ifdef UNION_ANY_DEFINITION
@@ -1657,7 +1770,8 @@ union any {
     I32                any_i32;
     IV         any_iv;
     long       any_long;
-    void       (*any_dptr) (pTHXo_ void*);
+    void       (*any_dptr) (void*);
+    void       (*any_dxptr) (pTHXo_ void*);
 };
 #endif
 
@@ -1667,38 +1781,29 @@ union any {
 #define ARGSproto
 #endif /* USE_THREADS */
 
-#if defined(CYGWIN32)
-/* USEMYBINMODE
- *   This symbol, if defined, indicates that the program should
- *   use the routine my_binmode(FILE *fp, char iotype) to insure
- *   that a file is in "binary" mode -- that is, that no translation
- *   of bytes occurs on read or write operations.
- */
-#define USEMYBINMODE / **/
-#define my_binmode(fp, iotype) \
-        (PerlLIO_setmode(PerlIO_fileno(fp), O_BINARY) != -1 ? TRUE : FALSE)
-#endif
-
 typedef I32 (*filter_t) (pTHXo_ int, SV *, int);
 
 #define FILTER_READ(idx, sv, len)  filter_read(idx, sv, len)
 #define FILTER_DATA(idx)          (AvARRAY(PL_rsfp_filters)[idx])
 #define FILTER_ISREADER(idx)      (idx >= AvFILLp(PL_rsfp_filters))
 
-#include "iperlsys.h"
+#if !defined(OS2)
+#  include "iperlsys.h"
+#endif
 #include "regexp.h"
 #include "sv.h"
 #include "util.h"
 #include "form.h"
 #include "gv.h"
 #include "cv.h"
+#include "opnames.h"
 #include "op.h"
 #include "cop.h"
 #include "av.h"
 #include "hv.h"
 #include "mg.h"
 #include "scope.h"
-#include "warning.h"
+#include "warnings.h"
 #include "utf8.h"
 
 /* Current curly descriptor */
@@ -1726,25 +1831,7 @@ struct _sublex_info {
 
 typedef struct magic_state MGS;        /* struct magic_state defined in mg.c */
 
-/* Length of a variant. */
-
-typedef struct {
-    I32 len_min;
-    I32 len_delta;
-    I32 pos_min;
-    I32 pos_delta;
-    SV *last_found;
-    I32 last_end;                      /* min value, <0 unless valid. */
-    I32 last_start_min;
-    I32 last_start_max;
-    SV **longest;                      /* Either &l_fixed, or &l_float. */
-    SV *longest_fixed;
-    I32 offset_fixed;
-    SV *longest_float;
-    I32 offset_float_min;
-    I32 offset_float_max;
-    I32 flags;
-} scan_data_t;
+struct scan_data_t;            /* Used in S_* functions in regcomp.c */
 
 typedef I32 CHECKPOINT;
 
@@ -1826,6 +1913,46 @@ typedef I32 CHECKPOINT;
 #define U_V(what) (cast_uv((NV)(what)))
 #endif
 
+/* These do not care about the fractional part, only about the range. */
+#define NV_WITHIN_IV(nv) (I_V(nv) >= IV_MIN && I_V(nv) <= IV_MAX)
+#define NV_WITHIN_UV(nv) ((nv)>=0.0 && U_V(nv) >= UV_MIN && U_V(nv) <= UV_MAX)
+
+/* Believe. */
+#define IV_FITS_IN_NV
+/* Doubt. */
+#if defined(USE_LONG_DOUBLE) && \
+       defined(LDBL_MANT_DIG) && IV_DIG >= LDBL_MANT_DIG
+#   undef IV_FITS_IN_NV
+#else
+#   if defined(DBL_MANT_DIG) && IV_DIG >= DBL_MANT_DIG
+#       undef IV_FITS_IN_NV
+#   else
+#       if IV_DIG >= NV_DIG
+#           undef IV_FITS_IN_NV
+#       else
+#           if IVSIZE >= NVSIZE
+#               undef IV_FITS_IN_NV
+#           endif
+#       endif
+#   endif
+#endif
+
+#ifdef IV_IS_QUAD
+#  define UVuf PERL_PRIu64
+#  define IVdf PERL_PRId64
+#  define UVof PERL_PRIo64
+#  define UVxf PERL_PRIx64
+#else
+#   if LONGSIZE == 4
+#       define UVuf "lu"
+#       define IVdf "ld"
+#       define UVof "lo"
+#       define UVxf "lx"
+#   else
+        /* Any good ideas? */
+#   endif
+#endif
+
 /* Used with UV/IV arguments: */
                                        /* XXXX: need to speed it up */
 #define CLUMP_2UV(iv)  ((iv) < 0 ? 0 : (UV)(iv))
@@ -1853,7 +1980,13 @@ Gid_t getegid (void);
 #endif
 
 #ifndef Perl_debug_log
-#define Perl_debug_log PerlIO_stderr()
+#  define Perl_debug_log       PerlIO_stderr()
+#endif
+
+#ifndef Perl_error_log
+#  define Perl_error_log       (PL_stderrgv                    \
+                                ? IoOFP(GvIOp(PL_stderrgv))    \
+                                : PerlIO_stderr())
 #endif
 
 #ifdef DEBUGGING
@@ -1871,7 +2004,10 @@ Gid_t getegid (void);
 #  if defined(PERL_OBJECT)
 #    define DEBUG_m(a) if (PL_debug & 128)     a
 #  else
-#    define DEBUG_m(a) if (PERL_GET_INTERP && PL_debug & 128)  a
+#    define DEBUG_m(a)  \
+    STMT_START {                                                       \
+       if (PERL_GET_INTERP) { dTHX; if (PL_debug & 128) { a; } }       \
+    } STMT_END
 #  endif
 #define DEBUG_f(a) if (PL_debug & 256) a
 #define DEBUG_r(a) if (PL_debug & 512) a
@@ -1927,8 +2063,10 @@ struct ufuncs {
 /* Fix these up for __STDC__ */
 #ifndef DONT_DECLARE_STD
 char *mktemp (char*);
+#ifndef atof
 double atof (const char*);
 #endif
+#endif
 
 #ifndef STANDARD_C
 /* All of these are in stdlib.h or time.h for ANSI C */
@@ -2001,7 +2139,7 @@ I32 unlnk (char*);
 #  endif
 #endif
 
-typedef Signal_t (*Sighandler_t) (int);
+/* Sighandler_t defined in iperlsys.h */
 
 #ifdef HAS_SIGACTION
 typedef struct sigaction Sigsave_t;
@@ -2355,6 +2493,8 @@ typedef enum {
     XREF,
     XSTATE,
     XBLOCK,
+    XATTRBLOCK,
+    XATTRTERM,
     XTERMBLOCK
 } expectation;
 
@@ -2442,6 +2582,7 @@ typedef void      (CPERLscope(*regfree_t)) (pTHX_ struct regexp* r);
 int Perl_yylex(pTHX_ YYSTYPE *lvalp, int *lcharp);
 #endif
 
+typedef void (*DESTRUCTORFUNC_NOCONTEXT_t) (void*);
 typedef void (*DESTRUCTORFUNC_t) (pTHXo_ void*);
 typedef void (*SVFUNC_t) (pTHXo_ SV*);
 typedef I32  (*SVCOMPARE_t) (pTHXo_ SV*, SV*);
@@ -2478,6 +2619,7 @@ public:
        CPerlObj(IPerlMem*, IPerlEnv*, IPerlStdIO*, IPerlLIO*, IPerlDir*, IPerlSock*, IPerlProc*);
        void Init(void);
        void* operator new(size_t nSize, IPerlMem *pvtbl);
+       static void operator delete(void* pPerl, IPerlMem *pvtbl);
 #endif /* PERL_OBJECT */
 
 #ifdef PERL_GLOBAL_STRUCT
@@ -2489,11 +2631,11 @@ struct perl_vars {
 EXT struct perl_vars PL_Vars;
 EXT struct perl_vars *PL_VarsPtr INIT(&PL_Vars);
 #else /* PERL_CORE */
-#if !defined(__GNUC__) || !(defined(WIN32) || defined(CYGWIN32))
+#if !defined(__GNUC__) || !defined(WIN32)
 EXT
 #endif /* WIN32 */
 struct perl_vars *PL_VarsPtr;
-#define PL_Vars (*((PL_VarsPtr) ? PL_VarsPtr : (PL_VarsPtr =  Perl_GetVars())))
+#define PL_Vars (*((PL_VarsPtr) ? PL_VarsPtr : (PL_VarsPtr = Perl_GetVars(aTHX))))
 #endif /* PERL_CORE */
 #endif /* PERL_GLOBAL_STRUCT */
 
@@ -2505,7 +2647,9 @@ struct perl_vars *PL_VarsPtr;
 */
 
 struct interpreter {
-#include "thrdvar.h"
+#ifndef USE_THREADS
+#  include "thrdvar.h"
+#endif
 #include "intrpvar.h"
 };
 
@@ -2657,85 +2801,85 @@ START_EXTERN_C
 
 #ifdef DOINIT
 
-EXT MGVTBL PL_vtbl_sv =        {Perl_magic_get,
-                               Perl_magic_set,
-                                       Perl_magic_len,
+EXT MGVTBL PL_vtbl_sv =        {MEMBER_TO_FPTR(Perl_magic_get),
+                               MEMBER_TO_FPTR(Perl_magic_set),
+                                       MEMBER_TO_FPTR(Perl_magic_len),
                                                0,      0};
-EXT MGVTBL PL_vtbl_env =       {0,     Perl_magic_set_all_env,
-                               0,      Perl_magic_clear_all_env,
+EXT MGVTBL PL_vtbl_env =       {0,     MEMBER_TO_FPTR(Perl_magic_set_all_env),
+                               0,      MEMBER_TO_FPTR(Perl_magic_clear_all_env),
                                                        0};
-EXT MGVTBL PL_vtbl_envelem =   {0,     Perl_magic_setenv,
-                                       0,      Perl_magic_clearenv,
+EXT MGVTBL PL_vtbl_envelem =   {0,     MEMBER_TO_FPTR(Perl_magic_setenv),
+                                       0,      MEMBER_TO_FPTR(Perl_magic_clearenv),
                                                        0};
 EXT MGVTBL PL_vtbl_sig =       {0,     0,               0, 0, 0};
-EXT MGVTBL PL_vtbl_sigelem =   {Perl_magic_getsig,
-                                       Perl_magic_setsig,
-                                       0,      Perl_magic_clearsig,
+EXT MGVTBL PL_vtbl_sigelem =   {MEMBER_TO_FPTR(Perl_magic_getsig),
+                                       MEMBER_TO_FPTR(Perl_magic_setsig),
+                                       0,      MEMBER_TO_FPTR(Perl_magic_clearsig),
                                                        0};
-EXT MGVTBL PL_vtbl_pack =      {0,     0,      Perl_magic_sizepack,    Perl_magic_wipepack,
+EXT MGVTBL PL_vtbl_pack =      {0,     0,      MEMBER_TO_FPTR(Perl_magic_sizepack),    MEMBER_TO_FPTR(Perl_magic_wipepack),
                                                        0};
-EXT MGVTBL PL_vtbl_packelem =  {Perl_magic_getpack,
-                               Perl_magic_setpack,
-                                       0,      Perl_magic_clearpack,
+EXT MGVTBL PL_vtbl_packelem =  {MEMBER_TO_FPTR(Perl_magic_getpack),
+                               MEMBER_TO_FPTR(Perl_magic_setpack),
+                                       0,      MEMBER_TO_FPTR(Perl_magic_clearpack),
                                                        0};
-EXT MGVTBL PL_vtbl_dbline =    {0,     Perl_magic_setdbline,
+EXT MGVTBL PL_vtbl_dbline =    {0,     MEMBER_TO_FPTR(Perl_magic_setdbline),
                                        0,      0,      0};
-EXT MGVTBL PL_vtbl_isa =       {0,     Perl_magic_setisa,
-                                       0,      Perl_magic_setisa,
+EXT MGVTBL PL_vtbl_isa =       {0,     MEMBER_TO_FPTR(Perl_magic_setisa),
+                                       0,      MEMBER_TO_FPTR(Perl_magic_setisa),
                                                        0};
-EXT MGVTBL PL_vtbl_isaelem =   {0,     Perl_magic_setisa,
+EXT MGVTBL PL_vtbl_isaelem =   {0,     MEMBER_TO_FPTR(Perl_magic_setisa),
                                        0,      0,      0};
-EXT MGVTBL PL_vtbl_arylen =    {Perl_magic_getarylen,
-                               Perl_magic_setarylen,
+EXT MGVTBL PL_vtbl_arylen =    {MEMBER_TO_FPTR(Perl_magic_getarylen),
+                               MEMBER_TO_FPTR(Perl_magic_setarylen),
                                        0,      0,      0};
-EXT MGVTBL PL_vtbl_glob =      {Perl_magic_getglob,
-                               Perl_magic_setglob,
+EXT MGVTBL PL_vtbl_glob =      {MEMBER_TO_FPTR(Perl_magic_getglob),
+                               MEMBER_TO_FPTR(Perl_magic_setglob),
                                        0,      0,      0};
-EXT MGVTBL PL_vtbl_mglob =     {0,     Perl_magic_setmglob,
+EXT MGVTBL PL_vtbl_mglob =     {0,     MEMBER_TO_FPTR(Perl_magic_setmglob),
                                        0,      0,      0};
-EXT MGVTBL PL_vtbl_nkeys =     {Perl_magic_getnkeys,
-                               Perl_magic_setnkeys,
+EXT MGVTBL PL_vtbl_nkeys =     {MEMBER_TO_FPTR(Perl_magic_getnkeys),
+                               MEMBER_TO_FPTR(Perl_magic_setnkeys),
                                        0,      0,      0};
-EXT MGVTBL PL_vtbl_taint =     {Perl_magic_gettaint,Perl_magic_settaint,
+EXT MGVTBL PL_vtbl_taint =     {MEMBER_TO_FPTR(Perl_magic_gettaint),MEMBER_TO_FPTR(Perl_magic_settaint),
                                        0,      0,      0};
-EXT MGVTBL PL_vtbl_substr =    {Perl_magic_getsubstr, Perl_magic_setsubstr,
+EXT MGVTBL PL_vtbl_substr =    {MEMBER_TO_FPTR(Perl_magic_getsubstr), MEMBER_TO_FPTR(Perl_magic_setsubstr),
                                        0,      0,      0};
-EXT MGVTBL PL_vtbl_vec =       {Perl_magic_getvec,
-                               Perl_magic_setvec,
+EXT MGVTBL PL_vtbl_vec =       {MEMBER_TO_FPTR(Perl_magic_getvec),
+                               MEMBER_TO_FPTR(Perl_magic_setvec),
                                        0,      0,      0};
-EXT MGVTBL PL_vtbl_pos =       {Perl_magic_getpos,
-                               Perl_magic_setpos,
+EXT MGVTBL PL_vtbl_pos =       {MEMBER_TO_FPTR(Perl_magic_getpos),
+                               MEMBER_TO_FPTR(Perl_magic_setpos),
                                        0,      0,      0};
-EXT MGVTBL PL_vtbl_bm =        {0,     Perl_magic_setbm,
+EXT MGVTBL PL_vtbl_bm =        {0,     MEMBER_TO_FPTR(Perl_magic_setbm),
                                        0,      0,      0};
-EXT MGVTBL PL_vtbl_fm =        {0,     Perl_magic_setfm,
+EXT MGVTBL PL_vtbl_fm =        {0,     MEMBER_TO_FPTR(Perl_magic_setfm),
                                        0,      0,      0};
-EXT MGVTBL PL_vtbl_uvar =      {Perl_magic_getuvar,
-                               Perl_magic_setuvar,
+EXT MGVTBL PL_vtbl_uvar =      {MEMBER_TO_FPTR(Perl_magic_getuvar),
+                               MEMBER_TO_FPTR(Perl_magic_setuvar),
                                        0,      0,      0};
 #ifdef USE_THREADS
-EXT MGVTBL PL_vtbl_mutex =     {0,     0,      0,      0,      Perl_magic_mutexfree};
+EXT MGVTBL PL_vtbl_mutex =     {0,     0,      0,      0,      MEMBER_TO_FPTR(Perl_magic_mutexfree)};
 #endif /* USE_THREADS */
-EXT MGVTBL PL_vtbl_defelem = {Perl_magic_getdefelem,Perl_magic_setdefelem,
+EXT MGVTBL PL_vtbl_defelem = {MEMBER_TO_FPTR(Perl_magic_getdefelem),MEMBER_TO_FPTR(Perl_magic_setdefelem),
                                        0,      0,      0};
 
-EXT MGVTBL PL_vtbl_regexp = {0,0,0,0, Perl_magic_freeregexp};
-EXT MGVTBL PL_vtbl_regdata = {0, 0, Perl_magic_regdata_cnt, 0, 0};
-EXT MGVTBL PL_vtbl_regdatum = {Perl_magic_regdatum_get, 0, 0, 0, 0};
+EXT MGVTBL PL_vtbl_regexp = {0,0,0,0, MEMBER_TO_FPTR(Perl_magic_freeregexp)};
+EXT MGVTBL PL_vtbl_regdata = {0, 0, MEMBER_TO_FPTR(Perl_magic_regdata_cnt), 0, 0};
+EXT MGVTBL PL_vtbl_regdatum = {MEMBER_TO_FPTR(Perl_magic_regdatum_get), 0, 0, 0, 0};
 
 #ifdef USE_LOCALE_COLLATE
 EXT MGVTBL PL_vtbl_collxfrm = {0,
-                               Perl_magic_setcollxfrm,
+                               MEMBER_TO_FPTR(Perl_magic_setcollxfrm),
                                        0,      0,      0};
 #endif
 
-EXT MGVTBL PL_vtbl_amagic =       {0,     Perl_magic_setamagic,
-                                        0,      0,      Perl_magic_setamagic};
-EXT MGVTBL PL_vtbl_amagicelem =   {0,     Perl_magic_setamagic,
-                                        0,      0,      Perl_magic_setamagic};
+EXT MGVTBL PL_vtbl_amagic =       {0,     MEMBER_TO_FPTR(Perl_magic_setamagic),
+                                        0,      0,      MEMBER_TO_FPTR(Perl_magic_setamagic)};
+EXT MGVTBL PL_vtbl_amagicelem =   {0,     MEMBER_TO_FPTR(Perl_magic_setamagic),
+                                        0,      0,      MEMBER_TO_FPTR(Perl_magic_setamagic)};
 
 EXT MGVTBL PL_vtbl_backref =     {0,   0,
-                                       0,      0,      Perl_magic_killbackrefs};
+                                       0,      0,      MEMBER_TO_FPTR(Perl_magic_killbackrefs)};
 
 #else /* !DOINIT */
 
@@ -2971,6 +3115,18 @@ typedef struct am_table_short AMTS;
 
 #endif /* !USE_LOCALE_NUMERIC */
 
+#if defined(USE_LONG_LONG) && defined(HAS_LONG_LONG) && defined(HAS_ATOLL)
+#define Atol atoll 
+#else
+#define Atol atol
+#endif
+
+#if defined(USE_LONG_LONG) && defined(HAS_LONG_LONG) && defined(HAS_STRTOULL)
+#define Strtoul strtoull
+#else
+#define Strtoul strtoul
+#endif
+
 #if !defined(PERLIO_IS_STDIO) && defined(HASATTRIBUTE)
 /* 
  * Now we have __attribute__ out of the way 
@@ -3004,12 +3160,21 @@ typedef struct am_table_short AMTS;
 #   include <sys/sem.h>
 #   ifndef HAS_UNION_SEMUN     /* Provide the union semun. */
     union semun {
-       int val;
-       struct semid_ds *buf;
-       unsigned short *array;
+       int             val;
+       struct semid_ds *buf;
+       unsigned short  *array;
     };
 #   endif
 #   ifdef USE_SEMCTL_SEMUN
+#      ifdef IRIX32_SEMUN_BROKEN_BY_GCC
+            union gccbug_semun {
+               int             val;
+               struct semid_ds *buf;
+               unsigned short  *array;
+               char            __dummy[5];
+           };
+#           define semun gccbug_semun
+#      endif
 #       define Semctl(id, num, cmd, semun) semctl(id, num, cmd, semun)
 #   else
 #       ifdef USE_SEMCTL_SEMID_DS