This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Long double support: sqrtl et al are not available everywhere,
[perl5.git] / perl.h
diff --git a/perl.h b/perl.h
index 613f84f..501c635 100644 (file)
--- a/perl.h
+++ b/perl.h
@@ -31,7 +31,9 @@
 #    define PERL_IMPLICIT_CONTEXT
 #  endif
 #  ifndef PERL_IMPLICIT_SYS
-/*#    define PERL_IMPLICIT_SYS*/              /* XXX not done yet */
+#    ifdef WIN32
+#      define PERL_IMPLICIT_SYS                /* XXX not implemented everywhere yet */
+#    endif
 #  endif
 #endif
 
@@ -40,7 +42,9 @@
 #    define PERL_IMPLICIT_CONTEXT
 #  endif
 #  ifndef PERL_IMPLICIT_SYS
-/*#    define PERL_IMPLICIT_SYS*/              /* XXX not done yet */
+#    ifdef WIN32
+#      define PERL_IMPLICIT_SYS                /* XXX not implemented everywhere yet */
+#    endif
 #  endif
 #endif
 
@@ -86,8 +90,8 @@ the perl interpreter.
 | Perl Host |
 +-----------+
       ^
-         |
-         v
+      |
+      v
 +-----------+   +-----------+
 | Perl Core |<->| Extension |
 +-----------+   +-----------+ ...
@@ -389,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
 
@@ -470,10 +474,6 @@ register struct op *Perl_op asm(stringify(OP_IN_REGISTER));
 #  include "embed.h"
 #endif
 
-#if defined(NeXT) || defined(__NeXT) || defined (__MACHTEN__)
-#  undef PERL_POLLUTE_MALLOC
-#endif
-
 #define MEM_SIZE Size_t
 
 #if defined(STANDARD_C) && defined(I_STDDEF)
@@ -688,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
@@ -895,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
@@ -921,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
@@ -1027,7 +1022,11 @@ Free_t   Perl_mfree (Malloc_t where);
 #  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
@@ -1049,12 +1048,36 @@ Free_t   Perl_mfree (Malloc_t where);
 #  define IVSIZE LONGSIZE
 #endif
 #define IV_DIG (BIT_DIGITS(IVSIZE * 8))
-#define UV_DIG (BIT_DIGITS(IVSIZE * 8))
+#define UV_DIG (BIT_DIGITS(UVSIZE * 8))
 
-#ifdef USE_LONG_DOUBLE
-#  if defined(HAS_LONG_DOUBLE) && (LONG_DOUBLESIZE > DOUBLESIZE)
-#    define LDoub_t long double
+/*   
+ *  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))
 #     undef USE_LONG_DOUBLE /* Ouch! */
 #  endif
 #endif
@@ -1098,43 +1121,48 @@ Free_t   Perl_mfree (Malloc_t where);
    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
+# 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 == 12
+#    define LDBL_DIG 18 /* gcc? */
+#   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
 #endif
 
 #ifdef USE_LONG_DOUBLE
-#   define HAS_LDOUB
-    typedef LDoub_t NV;
+    typedef long double NV;
 #   define NVSIZE LONG_DOUBLESIZE
 #   define NV_DIG LDBL_DIG
-#   define Perl_modf modfl
-#   define Perl_frexp frexpl
-#   define Perl_cos cosl
-#   define Perl_sin sinl
-#   define Perl_sqrt sqrtl
-#   define Perl_exp expl
-#   define Perl_log logl
-#   define Perl_atan2 atan2l
-#   define Perl_pow powl
-#   define Perl_floor floorl
-#   define Perl_fmod fmodl
+#   ifdef HAS_SQRTL
+#       define Perl_modf modfl
+#       define Perl_frexp frexpl
+#       define Perl_cos cosl
+#       define Perl_sin sinl
+#       define Perl_sqrt sqrtl
+#       define Perl_exp expl
+#       define Perl_log logl
+#       define Perl_atan2 atan2l
+#       define Perl_pow powl
+#       define Perl_floor floorl
+#       define Perl_fmod fmodl
+#   endif
 #else
     typedef double NV;
 #   define NVSIZE DOUBLESIZE
@@ -1367,9 +1395,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;
@@ -1401,15 +1426,17 @@ typedef union any ANY;
 
 #include "handy.h"
 
-#ifdef USE_64_BITS
-#   define USE_64_BIT_FILES
+#if defined(USE_LARGE_FILES)
+#   define USE_64_BIT_RAWIO /* Explicit */
+#   define USE_64_BIT_STDIO
 #endif
 
-#if defined(USE_64_BIT_FILES) || defined(USE_LARGE_FILES)
-#   define USE_64_BIT_OFFSETS
-#   define USE_64_BIT_STDIO
+#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
@@ -1422,7 +1449,7 @@ typedef union any ANY;
 #define USE_FREOPEN64
 #endif
 
-#ifdef USE_64_BIT_OFFSETS
+#ifdef USE_64_BIT_RAWIO
 #   ifdef HAS_OFF64_T
 #       undef Off_t
 #       define Off_t off64_t
@@ -1431,7 +1458,7 @@ typedef union any ANY;
 #   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. */
+ * however, do not.  Therefore we have to explicitly mix and match. */
 #   if defined(USE_OPEN64)
 #       define open open64
 #   endif
@@ -1589,7 +1616,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;
@@ -1659,7 +1688,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)
@@ -1741,7 +1769,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
 
@@ -1907,6 +1936,22 @@ typedef I32 CHECKPOINT;
 #   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))
@@ -1934,7 +1979,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
@@ -2011,8 +2062,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 */
@@ -2528,6 +2581,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*);
@@ -3105,12 +3159,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