#ifdef PERL_MICRO
# include "uconfig.h"
#else
-# ifndef USE_CROSS_COMPILE
-# include "config.h"
-# else
-# include "xconfig.h"
-# endif
+# include "config.h"
#endif
/* See L<perlguts/"The Perl API"> for detailed notes on
# define USE_HEAP_INSTEAD_OF_STACK
#endif
-#/* Use the reentrant APIs like localtime_r and getpwent_r */
+/* Use the reentrant APIs like localtime_r and getpwent_r */
/* Win32 has naturally threadsafe libraries, no need to use any _r variants. */
#if defined(USE_ITHREADS) && !defined(USE_REENTRANT_API) && !defined(NETWARE) && !defined(WIN32) && !defined(PERL_DARWIN)
# define USE_REENTRANT_API
/* <--- here ends the logic shared by perl.h and makedef.pl */
-/*
- * PERL_DARWIN for MacOSX (__APPLE__ exists but is not officially sanctioned)
- * (The -DPERL_DARWIN comes from the hints/darwin.sh.)
- * __bsdi__ for BSD/OS
- */
-#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(PERL_DARWIN) || defined(__bsdi__) || defined(BSD41) || defined(BSD42) || defined(BSD43) || defined(BSD44)
-# ifndef BSDish
-# define BSDish
-# endif
+/* Microsoft Visual C++ 6.0 needs special treatment in numerous places */
+#if defined(WIN32) && defined(_MSC_VER) && _MSC_VER >= 1200 && _MSC_VER < 1300
+# define USING_MSVC6
#endif
#undef START_EXTERN_C
# define pTHX_7 8
# define pTHX_8 9
# define pTHX_9 10
+# define pTHX_12 13
# if defined(DEBUGGING) && !defined(PERL_TRACK_MEMPOOL)
# define PERL_TRACK_MEMPOOL
# endif
# define PERL_UNUSED_VAR(x) ((void)x)
#endif
-#ifdef USE_ITHREADS
+#if defined(USE_ITHREADS) || defined(PERL_GLOBAL_STRUCT)
# define PERL_UNUSED_CONTEXT PERL_UNUSED_ARG(my_perl)
#else
# define PERL_UNUSED_CONTEXT
#endif
+/* gcc (-ansi) -pedantic doesn't allow gcc statement expressions,
+ * g++ allows them but seems to have problems with them
+ * (insane errors ensue).
+ * g++ does not give insane errors now (RMB 2008-01-30, gcc 4.2.2).
+ */
+#if defined(PERL_GCC_PEDANTIC) || \
+ (defined(__GNUC__) && defined(__cplusplus) && \
+ ((__GNUC__ < 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ < 2))))
+# ifndef PERL_GCC_BRACE_GROUPS_FORBIDDEN
+# define PERL_GCC_BRACE_GROUPS_FORBIDDEN
+# endif
+#endif
+
+/* Use PERL_UNUSED_RESULT() to suppress the warnings about unused results
+ * of function calls, e.g. PERL_UNUSED_RESULT(foo(a, b)).
+ *
+ * The main reason for this is that the combination of gcc -Wunused-result
+ * (part of -Wall) and the __attribute__((warn_unused_result)) cannot
+ * be silenced with casting to void. This causes trouble when the system
+ * header files use the attribute.
+ *
+ * Use PERL_UNUSED_RESULT sparingly, though, since usually the warning
+ * is there for a good reason: you might lose success/failure information,
+ * or leak resources, or changes in resources.
+ *
+ * But sometimes you just want to ignore the return value, e.g. on
+ * codepaths soon ending up in abort, or in "best effort" attempts,
+ * or in situations where there is no good way to handle failures.
+ *
+ * Sometimes PERL_UNUSED_RESULT might not be the most natural way:
+ * another possibility is that you can capture the return value
+ * and use PERL_UNUSED_VAR on that.
+ *
+ * The __typeof__() is used instead of typeof() since typeof() is not
+ * available under strict C89, and because of compilers masquerading
+ * as gcc (clang and icc), we want exactly the gcc extension
+ * __typeof__ and nothing else.
+ */
+#ifndef PERL_UNUSED_RESULT
+# if defined(__GNUC__) && defined(HASATTRIBUTE_WARN_UNUSED_RESULT)
+# define PERL_UNUSED_RESULT(v) STMT_START { __typeof__(v) z = (v); (void)sizeof(z); } STMT_END
+# else
+# define PERL_UNUSED_RESULT(v) ((void)(v))
+# endif
+#endif
+
+/* on gcc (and clang), specify that a warning should be temporarily
+ * ignored; e.g.
+ *
+ * GCC_DIAG_IGNORE(-Wmultichar);
+ * char b = 'ab';
+ * GCC_DIAG_RESTORE;
+ *
+ * based on http://dbp-consulting.com/tutorials/SuppressingGCCWarnings.html
+ *
+ * Note that "pragma GCC diagnostic push/pop" was added in GCC 4.6, Mar 2011;
+ * clang only pretends to be GCC 4.2, but still supports push/pop.
+ *
+ * Note on usage: on non-gcc (or lookalike, like clang) compilers
+ * one cannot use these at file (global) level without warnings
+ * since they are defined as empty, which leads into the terminating
+ * semicolon being left alone on a line:
+ * ;
+ * which makes compilers mildly cranky. Therefore at file level one
+ * should use the GCC_DIAG_IGNORE and GCC_DIAG_RESTORE_FILE *without*
+ * the semicolons.
+ *
+ * (A dead-on-arrival solution would be to try to define the macros as
+ * NOOP or dNOOP, those don't work both inside functions and outside.)
+ */
+
+#if defined(__clang__) || defined(__clang) || \
+ (defined( __GNUC__) && ((__GNUC__ * 100) + __GNUC_MINOR__) >= 406)
+# define GCC_DIAG_PRAGMA(x) _Pragma (#x)
+/* clang has "clang diagnostic" pragmas, but also understands gcc. */
+# define GCC_DIAG_IGNORE(x) _Pragma("GCC diagnostic push") \
+ GCC_DIAG_PRAGMA(GCC diagnostic ignored #x)
+# define GCC_DIAG_RESTORE _Pragma("GCC diagnostic pop")
+#else
+# define GCC_DIAG_IGNORE(w)
+# define GCC_DIAG_RESTORE
+#endif
+
#define NOOP /*EMPTY*/(void)0
/* cea2e8a9dd23747f accidentally lost the comment originally from the first
check in of thread.h, explaining why we need dNOOP at all: */
#endif
#ifndef pTHX
-/* Don't bother defining tTHX and sTHX; using them outside
+/* Don't bother defining tTHX ; using it outside
* code guarded by PERL_IMPLICIT_CONTEXT is an error.
*/
# define pTHX void
# define pTHX_7 7
# define pTHX_8 8
# define pTHX_9 9
+# define pTHX_12 12
#endif
#ifndef dVAR
# endif
#endif
-#ifdef OP_IN_REGISTER
-# ifdef __GNUC__
-# define stringify_immed(s) #s
-# define stringify(s) stringify_immed(s)
-struct op *Perl_op asm(stringify(OP_IN_REGISTER));
-# endif
-#endif
-
-/* gcc (-ansi) -pedantic doesn't allow gcc statement expressions,
- * g++ allows them but seems to have problems with them
- * (insane errors ensue).
- * g++ does not give insane errors now (RMB 2008-01-30, gcc 4.2.2).
- */
-#if defined(PERL_GCC_PEDANTIC) || \
- (defined(__GNUC__) && defined(__cplusplus) && \
- ((__GNUC__ < 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ < 2))))
-# ifndef PERL_GCC_BRACE_GROUPS_FORBIDDEN
-# define PERL_GCC_BRACE_GROUPS_FORBIDDEN
-# endif
-#endif
-
#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN) && !defined(__cplusplus)
# ifndef PERL_USE_GCC_BRACE_GROUPS
# define PERL_USE_GCC_BRACE_GROUPS
# define STMT_START (void)( /* gcc supports "({ STATEMENTS; })" */
# define STMT_END )
# else
- /* Now which other defined()s do we need here ??? */
-# if (defined(sun) || defined(__sun__)) && !defined(__GNUC__)
-# define STMT_START if (1)
-# define STMT_END else (void)0
-# else
# define STMT_START do
# define STMT_END while (0)
-# endif
# endif
#endif
* DANGER! Using NO_TAINT_SUPPORT or SILENT_NO_TAINT_SUPPORT
* voids your nonexistent warranty!
*/
-#if SILENT_NO_TAINT_SUPPORT && !defined(NO_TAINT_SUPPORT)
+#if defined(SILENT_NO_TAINT_SUPPORT) && !defined(NO_TAINT_SUPPORT)
# define NO_TAINT_SUPPORT 1
#endif
* operations into no-ops for a very modest speed-up. Enable only if you
* know what you're doing: tests and CPAN modules' tests are bound to fail.
*/
-#if NO_TAINT_SUPPORT
+#ifdef NO_TAINT_SUPPORT
# define TAINT NOOP
# define TAINT_NOT NOOP
# define TAINT_IF(c) NOOP
# include <pthread.h>
#endif
-#ifndef _TYPES_ /* If types.h defines this it's easy. */
-# ifndef major /* Does everyone's types.h define this? */
-# include <sys/types.h>
-# endif
-#endif
+#include <sys/types.h>
#ifdef __cplusplus
# ifndef I_STDARG
# endif
#endif
-#ifdef USE_NEXT_CTYPE
-
-#if NX_CURRENT_COMPILER_RELEASE >= 500
-# include <bsd/ctypes.h>
-#else
-# if NX_CURRENT_COMPILER_RELEASE >= 400
-# include <objc/NXCType.h>
-# else /* NX_CURRENT_COMPILER_RELEASE < 400 */
-# include <appkit/NXCType.h>
-# endif /* NX_CURRENT_COMPILER_RELEASE >= 400 */
-#endif /* NX_CURRENT_COMPILER_RELEASE >= 500 */
-
-#else /* !USE_NEXT_CTYPE */
#include <ctype.h>
-#endif /* USE_NEXT_CTYPE */
#ifdef METHOD /* Defined by OSF/1 v3.0 by ctype.h */
#undef METHOD
# if !defined(NO_LOCALE_MONETARY) && defined(LC_MONETARY)
# define USE_LOCALE_MONETARY
# endif
+# if !defined(NO_LOCALE_TIME) && defined(LC_TIME)
+# define USE_LOCALE_TIME
+# endif
+# ifndef WIN32 /* No wrapper except on Windows */
+# define my_setlocale(a,b) setlocale(a,b)
+# endif
#endif /* !NO_LOCALE && HAS_SETLOCALE */
#include <setjmp.h>
# include <sys/param.h>
#endif
+/* On BSD-derived systems, <sys/param.h> defines BSD to a year-month
+ value something like 199306. This may be useful if no more-specific
+ feature test is available.
+*/
+#if defined(BSD)
+# ifndef BSDish
+# define BSDish
+# endif
+#endif
+
/* Use all the "standard" definitions? */
#if defined(STANDARD_C) && defined(I_STDLIB)
# include <stdlib.h>
# define PERL_STRLEN_EXPAND_SHIFT 2
#endif
-#if defined(STANDARD_C) && defined(I_STDDEF)
+#if defined(STANDARD_C) && defined(I_STDDEF) && !defined(PERL_GCC_PEDANTIC)
# include <stddef.h>
# define STRUCT_OFFSET(s,m) offsetof(s,m)
#else
# define STRUCT_OFFSET(s,m) (Size_t)(&(((s *)0)->m))
#endif
+/* ptrdiff_t is C11, so undef it under pedantic builds */
+#ifdef PERL_GCC_PEDANTIC
+# undef HAS_PTRDIFF_T
+#endif
+
#ifndef __SYMBIAN32__
# if defined(I_STRING) || defined(__cplusplus)
# include <string.h>
# define CHECK_MALLOC_TAINT(newval) \
CHECK_MALLOC_TOO_LATE_FOR_( \
if (newval) { \
- panic_write2("panic: tainting with $ENV{PERL_MALLOC_OPT}\n");\
+ PERL_UNUSED_RESULT(panic_write2("panic: tainting with $ENV{PERL_MALLOC_OPT}\n"));\
exit(1); })
# define MALLOC_CHECK_TAINT(argc,argv,env) STMT_START { \
if (doing_taint(argc,argv,env)) { \
extern int memcmp (char*, char*, int);
# endif
# endif
-# ifdef BUGGY_MSC
-# pragma function(memcmp)
-# endif
#else
# ifndef memcmp
# define memcmp my_memcmp
# include <arpa/inet.h>
#endif
-#if defined(SF_APPEND) && defined(USE_SFIO) && defined(I_SFIO)
-/* <sfio.h> defines SF_APPEND and <sys/stat.h> might define SF_APPEND
- * (the neo-BSD seem to do this). */
-# undef SF_APPEND
-#endif
-
#ifdef I_SYS_STAT
# include <sys/stat.h>
#endif
#endif
#if defined(__cplusplus)
-# if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__)
+# if defined(BSDish)
EXTERN_C char **environ;
# elif defined(__CYGWIN__)
EXTERN_C char *crypt(const char *, const char *);
# define SS_DEVOFFLINE SS$_DEVOFFLINE
# define SS_IVCHAN SS$_IVCHAN
# define SS_NORMAL SS$_NORMAL
+# define SS_NOPRIV SS$_NOPRIV
#else
# define LIB_INVARG 0
# define RMS_DIR 0
# define SS_DEVOFFLINE 0
# define SS_IVCHAN 0
# define SS_NORMAL 0
+# define SS_NOPRIV 0
#endif
#ifdef WIN32
# define SAVE_DEFSV SAVESPTR(GvSV(PL_defgv))
#endif
-#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
* #define errno (*_errno()) */
#endif
+#define UNKNOWN_ERRNO_MSG "(unknown)"
+
#ifdef HAS_STRERROR
# ifndef DONT_DECLARE_STD
# ifdef VMS
extern char *sys_errlist[];
# ifndef Strerror
# define Strerror(e) \
- ((e) < 0 || (e) >= sys_nerr ? "(unknown)" : sys_errlist[e])
+ ((e) < 0 || (e) >= sys_nerr ? UNKNOWN_ERRNO_MSG : sys_errlist[e])
# endif
# endif
#endif
/* Configure already sets Direntry_t */
#if defined(I_DIRENT)
# include <dirent.h>
- /* NeXT needs dirent + sys/dir.h */
-# if defined(I_SYS_DIR) && (defined(NeXT) || defined(__NeXT__))
-# include <sys/dir.h>
-# endif
#else
# ifdef I_SYS_NDIR
# include <sys/ndir.h>
# endif
#endif
-#ifdef FPUTS_BOTCH
-/* work around botch in SunOS 4.0.1 and 4.0.2 */
-# ifndef fputs
-# define fputs(sv,fp) fprintf(fp,"%s",sv)
-# endif
-#endif
-
/*
* The following gobbledygook brought to you on behalf of __STDC__.
* (I could just use #ifndef __STDC__, but this is more bulletproof
# define S_IEXEC S_IXUSR
#endif
-#ifdef ff_next
-# undef ff_next
-#endif
-
#if defined(cray) || defined(gould) || defined(i860) || defined(pyr)
# define SLOPPYDIVIDE
#endif
* that should be true only if the snprintf()/vsnprintf() are true
* to the standard. */
+#define PERL_SNPRINTF_CHECK(len, max, api) STMT_START { if ((max) > 0 && (Size_t)len >= (max)) Perl_croak_nocontext("panic: %s buffer overflow", STRINGIFY(api)); } STMT_END
+
#if defined(HAS_SNPRINTF) && defined(HAS_C99_VARIADIC_MACROS) && !(defined(DEBUGGING) && !defined(PERL_USE_GCC_BRACE_GROUPS)) && !defined(PERL_GCC_PEDANTIC)
# ifdef PERL_USE_GCC_BRACE_GROUPS
-# define my_snprintf(buffer, len, ...) ({ int __len__ = snprintf(buffer, len, __VA_ARGS__); if ((len) > 0 && (Size_t)__len__ >= (len)) Perl_croak_nocontext("panic: snprintf buffer overflow"); __len__; })
+# define my_snprintf(buffer, max, ...) ({ int len = snprintf(buffer, max, __VA_ARGS__); PERL_SNPRINTF_CHECK(len, max, snprintf); len; })
# define PERL_MY_SNPRINTF_GUARDED
# else
-# define my_snprintf(buffer, len, ...) snprintf(buffer, len, __VA_ARGS__)
+# define my_snprintf(buffer, max, ...) snprintf(buffer, max, __VA_ARGS__)
# endif
#else
# define my_snprintf Perl_my_snprintf
#if defined(HAS_VSNPRINTF) && defined(HAS_C99_VARIADIC_MACROS) && !(defined(DEBUGGING) && !defined(PERL_USE_GCC_BRACE_GROUPS)) && !defined(PERL_GCC_PEDANTIC)
# ifdef PERL_USE_GCC_BRACE_GROUPS
-# define my_vsnprintf(buffer, len, ...) ({ int __len__ = vsnprintf(buffer, len, __VA_ARGS__); if ((len) > 0 && (Size_t)__len__ >= (Size_t)(len)) Perl_croak_nocontext("panic: vsnprintf buffer overflow"); __len__; })
+# define my_vsnprintf(buffer, max, ...) ({ int len = vsnprintf(buffer, max, __VA_ARGS__); PERL_SNPRINTF_CHECK(len, max, vsnprintf); len; })
# define PERL_MY_VSNPRINTF_GUARDED
# else
-# define my_vsnprintf(buffer, len, ...) vsnprintf(buffer, len, __VA_ARGS__)
+# define my_vsnprintf(buffer, max, ...) vsnprintf(buffer, max, __VA_ARGS__)
# endif
#else
# define my_vsnprintf Perl_my_vsnprintf
# define PERL_MY_VSNPRINTF_GUARDED
#endif
+/* You will definitely need to use the PERL_MY_SNPRINTF_POST_GUARD()
+ * or PERL_MY_VSNPRINTF_POST_GUARD() if you otherwise decide to ignore
+ * the result of my_snprintf() or my_vsnprintf(). (No, you should not
+ * completely ignore it: otherwise you cannot know whether your output
+ * was too long.)
+ *
+ * int len = my_sprintf(buf, max, ...);
+ * PERL_MY_SNPRINTF_POST_GUARD(len, max);
+ *
+ * The trick is that in certain platforms [a] the my_sprintf() already
+ * contains the sanity check, while in certain platforms [b] it needs
+ * to be done as a separate step. The POST_GUARD is that step-- in [a]
+ * platforms the POST_GUARD actually does nothing since the check has
+ * already been done. Watch out for the max being the same in both calls.
+ *
+ * If you actually use the snprintf/vsnprintf return value already,
+ * you assumedly are checking its validity somehow. But you can
+ * insert the POST_GUARD() also in that case. */
+
+#ifndef PERL_MY_SNPRINTF_GUARDED
+# define PERL_MY_SNPRINTF_POST_GUARD(len, max) PERL_SNPRINTF_CHECK(len, max, snprintf)
+#else
+# define PERL_MY_SNPRINTF_POST_GUARD(len, max) PERL_UNUSED_VAR(len)
+#endif
+
+#ifndef PERL_MY_VSNPRINTF_GUARDED
+# define PERL_MY_VSNPRINTF_POST_GUARD(len, max) PERL_SNPRINTF_CHECK(len, max, vsnprintf)
+#else
+# define PERL_MY_VSNPRINTF_POST_GUARD(len, max) PERL_UNUSED_VAR(len)
+#endif
+
#ifdef HAS_STRLCAT
# define my_strlcat strlcat
#else
# else
# undef IV_IS_QUAD
# undef UV_IS_QUAD
-#ifndef PERL_CORE
+#if !defined(PERL_CORE) || defined(USING_MSVC6)
/* We think that removing this decade-old undef this will cause too much
breakage on CPAN for too little gain. (See RT #119753)
- However, we do need HAS_QUAD in the core for use by the drand48 code. */
+ However, we do need HAS_QUAD in the core for use by the drand48 code,
+ but not for Win32 VC6 because it has poor __int64 support. */
# undef HAS_QUAD
#endif
# endif
#endif
-#define SSize_t_MAX (SSize_t)(~(size_t)0 >> 1)
-
-#ifndef HAS_QUAD
-# undef PERL_NEED_MY_HTOLE64
-# undef PERL_NEED_MY_LETOH64
-# undef PERL_NEED_MY_HTOBE64
-# undef PERL_NEED_MY_BETOH64
-#endif
+#define Size_t_MAX (~(Size_t)0)
+#define SSize_t_MAX (SSize_t)(~(Size_t)0 >> 1)
#define IV_DIG (BIT_DIGITS(IVSIZE * 8))
#define UV_DIG (BIT_DIGITS(UVSIZE * 8))
#endif
-struct RExC_state_t;
-struct _reg_trie_data;
-
typedef MEM_SIZE STRLEN;
-#ifdef PERL_MAD
-typedef struct token TOKEN;
-typedef struct madprop MADPROP;
-typedef struct nexttoken NEXTTOKE;
-#endif
typedef struct op OP;
typedef struct cop COP;
typedef struct unop UNOP;
# else
# include "dosish.h"
# endif
-# define ISHISH "dos"
-#endif
-
-#if defined(VMS)
+#elif defined(VMS)
# include "vmsish.h"
-# define ISHISH "vms"
-#endif
-
-#if defined(PLAN9)
+#elif defined(PLAN9)
# include "./plan9/plan9ish.h"
-# define ISHISH "plan9"
-#endif
-
-#if defined(__VOS__)
+#elif defined(__VOS__)
# ifdef __GNUC__
# include "./vos/vosish.h"
# else
# include "vos/vosish.h"
# endif
-# define ISHISH "vos"
-#endif
-
-#ifdef __SYMBIAN32__
+#elif defined(__SYMBIAN32__)
# include "symbian/symbianish.h"
-# define ISHISH "symbian"
-#endif
-
-
-#if defined(__HAIKU__)
+#elif defined(__HAIKU__)
# include "haiku/haikuish.h"
-# define ISHISH "haiku"
-#endif
-
-#ifndef ISHISH
+#else
# include "unixish.h"
-# define ISHISH "unix"
#endif
/* NSIG logic from Configure --> */
#endif
/*
+=head1 Miscellaneous Functions
+
=for apidoc Am|void|PERL_SYS_INIT|int *argc|char*** argv
Provides system-specific tune up of the C runtime environment necessary to
-run Perl interpreters. This should be called only once, before creating
+run Perl interpreters. This should be called only once, before creating
any Perl interpreters.
=for apidoc Am|void|PERL_SYS_INIT3|int *argc|char*** argv|char*** env
Provides system-specific tune up of the C runtime environment necessary to
-run Perl interpreters. This should be called only once, before creating
+run Perl interpreters. This should be called only once, before creating
any Perl interpreters.
=for apidoc Am|void|PERL_SYS_TERM|
Provides system-specific clean up of the C runtime environment after
-running Perl interpreters. This should be called only once, after
+running Perl interpreters. This should be called only once, after
freeing any remaining Perl interpreters.
=cut
# else
# ifdef I_MACH_CTHREADS
# include <mach/cthreads.h>
-# if (defined(NeXT) || defined(__NeXT__)) && defined(PERL_POLLUTE_MALLOC)
-# define MUTEX_INIT_CALLS_MALLOC
-# endif
typedef cthread_t perl_os_thread;
typedef mutex_t perl_mutex;
typedef condition_t perl_cond;
* out there, Solaris being the most prominent.
*/
#ifndef PERL_FLUSHALL_FOR_CHILD
-# if defined(USE_PERLIO) || defined(FFLUSH_NULL) || defined(USE_SFIO)
+# if defined(USE_PERLIO) || defined(FFLUSH_NULL)
# define PERL_FLUSHALL_FOR_CHILD PerlIO_flush((PerlIO*)NULL)
# else
# ifdef FFLUSH_ALL
/* Takes three arguments: is_utf8, length, str */
#ifndef UTF8f
-# define UTF8f "d%"UVuf"%4p"
+# define UTF8f "d%" UVuf "%4p"
#endif
#define UTF8fARG(u,l,p) (int)cBOOL(u), (UV)(l), (void*)(p)
#ifdef PERL_CORE
/* not used; but needed for backward compatibility with XS code? - RMB */
-# undef VDf
-#else
-# ifndef VDf
-# define VDf "vd"
-# endif
-#endif
-
-#ifdef PERL_CORE
-/* not used; but needed for backward compatibility with XS code? - RMB */
# undef UVf
#else
# ifndef UVf
# define __attribute__warn_unused_result__
#endif
+#if defined(DEBUGGING) && defined(I_ASSERT)
+# include <assert.h>
+#endif
+
/* For functions that are marked as __attribute__noreturn__, it's not
appropriate to call return. In either case, include the lint directive.
*/
#ifdef HASATTRIBUTE_NORETURN
-# define NORETURN_FUNCTION_END assert(0); /* NOTREACHED */
+# define NORETURN_FUNCTION_END NOT_REACHED; /* NOTREACHED */
#else
-# define NORETURN_FUNCTION_END assert(0); /* NOTREACHED */ return 0
+# define NORETURN_FUNCTION_END NOT_REACHED; /* NOTREACHED */ return 0
#endif
/* Some OS warn on NULL format to printf */
/* placeholder */
#endif
+
+#ifndef __has_builtin
+# define __has_builtin(x) 0 /* not a clang style compiler */
+#endif
+
+/* ASSUME is like assert(), but it has a benefit in a release build. It is a
+ hint to a compiler about a statement of fact in a function call free
+ expression, which allows the compiler to generate better machine code.
+ In a debug build, ASSUME(x) is a synonym for assert(x). ASSUME(0) means
+ the control path is unreachable. In a for loop, ASSUME can be used to hint
+ that a loop will run atleast X times. ASSUME is based off MSVC's __assume
+ intrinsic function, see its documents for more details.
+*/
+
+#ifndef DEBUGGING
+# if __has_builtin(__builtin_unreachable) \
+ || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5 || __GNUC__ > 5) /* 4.5 -> */
+# define ASSUME(x) ((x) ? (void) 0 : __builtin_unreachable())
+# elif defined(_MSC_VER)
+# define ASSUME(x) __assume(x)
+# elif defined(__ARMCC_VERSION) /* untested */
+# define ASSUME(x) __promise(x)
+# else
+/* a random compiler might define assert to its own special optimization token
+ so pass it through to C lib as a last resort */
+# define ASSUME(x) assert(x)
+# endif
+#else
+# define ASSUME(x) assert(x)
+#endif
+
+#define NOT_REACHED ASSUME(0)
+
/* 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 compiler. Sigh.
union any {
void* any_ptr;
I32 any_i32;
+ U32 any_u32;
IV any_iv;
UV any_uv;
long any_long;
&& idx >= AvFILLp(PL_parser->rsfp_filters))
#define PERL_FILTER_EXISTS(i) \
(PL_parser && PL_parser->rsfp_filters \
- && (i) <= av_len(PL_parser->rsfp_filters))
+ && (i) <= av_tindex(PL_parser->rsfp_filters))
#if defined(_AIX) && !defined(_AIX43)
#if defined(USE_REENTRANT) || defined(_REENTRANT) || defined(_THREAD_SAFE)
#endif
#include "perly.h"
-#ifdef PERL_MAD
-struct nexttoken {
- YYSTYPE next_val; /* value of next token, if any */
- I32 next_type; /* type of next token */
- MADPROP *next_mad; /* everything else about that token */
-};
-#endif
/* macros to define bit-fields in structs. */
#ifndef PERL_BITFIELD8
typedef struct magic_state MGS; /* struct magic_state defined in mg.c */
-struct scan_data_t; /* Used in S_* functions in regcomp.c */
-struct regnode_charclass_class; /* Used in S_* functions in regcomp.c */
+#if defined(PERL_IN_REGCOMP_C) || defined(PERL_IN_REGEXEC_C)
+
+/* These have to be predeclared, as they are used in proto.h which is #included
+ * before their definitions in regcomp.h. */
+
+struct scan_data_t;
+typedef struct regnode_charclass regnode_charclass;
+
+struct regnode_charclass_class;
+
+/* A hopefully less confusing name. The sub-classes are all Posix classes only
+ * used under /l matching */
+typedef struct regnode_charclass_class regnode_charclass_posixl;
+
+typedef struct regnode_ssc regnode_ssc;
+typedef struct RExC_state_t RExC_state_t;
+struct _reg_trie_data;
+
+#endif
struct ptr_tbl_ent {
struct ptr_tbl_ent* next;
#define U_32(n) ((n) < 0.0 ? ((n) < I32_MIN ? (UV) I32_MIN : (U32)(I32) (n)) \
: ((n) < U32_MAX_P1 ? (U32) (n) \
: ((n) > 0 ? U32_MAX : 0 /* NaN */)))
-#define I_V(n) ((n) < IV_MAX_P1 ? ((n) < IV_MIN ? IV_MIN : (IV) (n)) \
- : ((n) < UV_MAX_P1 ? (IV)(UV) (n) \
+#define I_V(n) (LIKELY((n) < IV_MAX_P1) ? (UNLIKELY((n) < IV_MIN) ? IV_MIN : (IV) (n)) \
+ : (LIKELY((n) < UV_MAX_P1) ? (IV)(UV) (n) \
: ((n) > 0 ? (IV)UV_MAX : 0 /* NaN */)))
-#define U_V(n) ((n) < 0.0 ? ((n) < IV_MIN ? (UV) IV_MIN : (UV)(IV) (n)) \
- : ((n) < UV_MAX_P1 ? (UV) (n) \
+#define U_V(n) ((n) < 0.0 ? (UNLIKELY((n) < IV_MIN) ? (UV) IV_MIN : (UV)(IV) (n)) \
+ : (LIKELY((n) < UV_MAX_P1) ? (UV) (n) \
: ((n) > 0 ? UV_MAX : 0 /* NaN */)))
#endif
#define DEBUG_q_FLAG 0x00800000 /*8388608 */
#define DEBUG_M_FLAG 0x01000000 /*16777216*/
#define DEBUG_B_FLAG 0x02000000 /*33554432*/
-#define DEBUG_MASK 0x03FFEFFF /* mask of all the standard flags */
+#define DEBUG_L_FLAG 0x04000000 /*67108864*/
+#define DEBUG_MASK 0x07FFEFFF /* mask of all the standard flags */
#define DEBUG_DB_RECURSE_FLAG 0x40000000
#define DEBUG_TOP_FLAG 0x80000000 /* XXX what's this for ??? Signal
# define DEBUG_q_TEST_ (PL_debug & DEBUG_q_FLAG)
# define DEBUG_M_TEST_ (PL_debug & DEBUG_M_FLAG)
# define DEBUG_B_TEST_ (PL_debug & DEBUG_B_FLAG)
+# define DEBUG_L_TEST_ (PL_debug & DEBUG_L_FLAG)
# define DEBUG_Xv_TEST_ (DEBUG_X_TEST_ && DEBUG_v_TEST_)
# define DEBUG_Uv_TEST_ (DEBUG_U_TEST_ && DEBUG_v_TEST_)
# define DEBUG_Pv_TEST_ (DEBUG_P_TEST_ && DEBUG_v_TEST_)
# define DEBUG_q_TEST DEBUG_q_TEST_
# define DEBUG_M_TEST DEBUG_M_TEST_
# define DEBUG_B_TEST DEBUG_B_TEST_
+# define DEBUG_L_TEST DEBUG_L_TEST_
# define DEBUG_Xv_TEST DEBUG_Xv_TEST_
# define DEBUG_Uv_TEST DEBUG_Uv_TEST_
# define DEBUG_Pv_TEST DEBUG_Pv_TEST_
# define DEBUG_q(a) DEBUG__(DEBUG_q_TEST, a)
# define DEBUG_M(a) DEBUG__(DEBUG_M_TEST, a)
# define DEBUG_B(a) DEBUG__(DEBUG_B_TEST, a)
+# define DEBUG_L(a) DEBUG__(DEBUG_L_TEST, a)
#else /* DEBUGGING */
# define DEBUG_q_TEST (0)
# define DEBUG_M_TEST (0)
# define DEBUG_B_TEST (0)
+# define DEBUG_L_TEST (0)
# define DEBUG_Xv_TEST (0)
# define DEBUG_Uv_TEST (0)
# define DEBUG_Pv_TEST (0)
# define DEBUG_q(a)
# define DEBUG_M(a)
# define DEBUG_B(a)
+# define DEBUG_L(a)
# define DEBUG_Xv(a)
# define DEBUG_Uv(a)
# define DEBUG_Pv(a)
where, (long)PL_scopestack_ix, (long)PL_savestack_ix, \
__FILE__, __LINE__));
-#if defined(DEBUGGING) && defined(I_ASSERT)
-# include <assert.h>
-#endif
-
/* Keep the old croak based assert for those who want it, and as a fallback if
the platform is so heretically non-ANSI that it can't assert. */
"\", line %d", STRINGIFY(what), __LINE__), \
(void) 0)))
+/* assert() gets defined if DEBUGGING (and I_ASSERT).
+ * If no DEBUGGING, the <assert.h> has not been included. */
#ifndef assert
# define assert(what) Perl_assert(what)
#endif
#endif
#ifndef __cplusplus
-# if defined(NeXT) || defined(__NeXT__) /* or whatever catches all NeXTs */
-char *crypt (); /* Maybe more hosts will need the unprototyped version */
-# else
-# if !defined(WIN32) && !defined(VMS)
+# if !defined(WIN32) && !defined(VMS)
#ifndef crypt
char *crypt (const char*, const char*);
#endif
-# endif /* !WIN32 */
-# endif /* !NeXT && !__NeXT__ */
+# endif /* !WIN32 */
# ifndef DONT_DECLARE_STD
# ifndef getenv
char *getenv (const char*);
# define RUNOPS_DEFAULT Perl_runops_standard
#endif
-#ifdef USE_PERLIO
+#if defined(USE_PERLIO)
EXTERN_C void PerlIO_teardown(void);
# ifdef USE_ITHREADS
# define PERLIO_INIT MUTEX_INIT(&PL_perlio_mutex)
struct perl_memory_debug_header;
struct perl_memory_debug_header {
tTHX interpreter;
-# ifdef PERL_POISON
+# if defined(PERL_POISON) || defined(PERL_DEBUG_READONLY_COW)
MEM_SIZE size;
# endif
struct perl_memory_debug_header *prev;
struct perl_memory_debug_header *next;
+# ifdef PERL_DEBUG_READONLY_COW
+ bool readonly;
+# endif
};
-# define sTHX (sizeof(struct perl_memory_debug_header) + \
+#elif defined(PERL_DEBUG_READONLY_COW)
+
+struct perl_memory_debug_header;
+struct perl_memory_debug_header {
+ MEM_SIZE size;
+};
+
+#endif
+
+#if defined (PERL_TRACK_MEMPOOL) || defined (PERL_DEBUG_READONLY_COW)
+
+# define PERL_MEMORY_DEBUG_HEADER_SIZE \
+ (sizeof(struct perl_memory_debug_header) + \
(MEM_ALIGNBYTES - sizeof(struct perl_memory_debug_header) \
%MEM_ALIGNBYTES) % MEM_ALIGNBYTES)
#else
-# define sTHX 0
+# define PERL_MEMORY_DEBUG_HEADER_SIZE 0
#endif
#ifdef PERL_TRACK_MEMPOOL
+# ifdef PERL_DEBUG_READONLY_COW
# define INIT_TRACK_MEMPOOL(header, interp) \
STMT_START { \
(header).interpreter = (interp); \
(header).prev = (header).next = &(header); \
+ (header).readonly = 0; \
} STMT_END
-# else
+# else
+# define INIT_TRACK_MEMPOOL(header, interp) \
+ STMT_START { \
+ (header).interpreter = (interp); \
+ (header).prev = (header).next = &(header); \
+ } STMT_END
+# endif
+# else
# define INIT_TRACK_MEMPOOL(header, interp)
#endif
#ifdef MYMALLOC
# define Perl_safesysmalloc_size(where) Perl_malloced_size(where)
#else
-# ifdef HAS_MALLOC_SIZE
+# if defined(HAS_MALLOC_SIZE) && !defined(PERL_DEBUG_READONLY_COW)
# ifdef PERL_TRACK_MEMPOOL
# define Perl_safesysmalloc_size(where) \
- (malloc_size(((char *)(where)) - sTHX) - sTHX)
+ (malloc_size(((char *)(where)) - PERL_MEMORY_DEBUG_HEADER_SIZE) - PERL_MEMORY_DEBUG_HEADER_SIZE)
# else
# define Perl_safesysmalloc_size(where) malloc_size(where)
# endif
# ifdef HAS_MALLOC_GOOD_SIZE
# ifdef PERL_TRACK_MEMPOOL
# define Perl_malloc_good_size(how_much) \
- (malloc_good_size((how_much) + sTHX) - sTHX)
+ (malloc_good_size((how_much) + PERL_MEMORY_DEBUG_HEADER_SIZE) - PERL_MEMORY_DEBUG_HEADER_SIZE)
# else
# define Perl_malloc_good_size(how_much) malloc_good_size(how_much)
# endif
typedef bool (*destroyable_proc_t) (pTHX_ SV *sv);
typedef void (*despatch_signals_proc_t) (pTHX);
-/* NeXT has problems with crt0.o globals */
-#if defined(__DYNAMIC__) && \
- (defined(NeXT) || defined(__NeXT__) || defined(PERL_DARWIN))
-# if defined(NeXT) || defined(__NeXT)
-# include <mach-o/dyld.h>
-# define environ (*environ_pointer)
-EXT char *** environ_pointer;
-# else
-# if defined(PERL_DARWIN) && defined(PERL_CORE)
-# include <crt_externs.h> /* for the env array */
-# define environ (*_NSGetEnviron())
-# endif
-# endif
+#if defined(__DYNAMIC__) && defined(PERL_DARWIN) && defined(PERL_CORE)
+# include <crt_externs.h> /* for the env array */
+# define environ (*_NSGetEnviron())
#else
/* VMS and some other platforms don't use the environ array */
# ifdef USE_ENVIRON_ARRAY
# if !defined(DONT_DECLARE_STD) || \
- (defined(__svr4__) && defined(__GNUC__) && defined(sun)) || \
+ (defined(__svr4__) && defined(__GNUC__) && defined(__sun)) || \
defined(__sgi)
extern char ** environ; /* environment variables supplied via exec */
# endif
EXTCONST char PL_warn_uninit[]
INIT("Use of uninitialized value%s%s%s");
EXTCONST char PL_warn_uninit_sv[]
- INIT("Use of uninitialized value%"SVf"%s%s");
+ INIT("Use of uninitialized value%" SVf "%s%s");
EXTCONST char PL_warn_nosemi[]
INIT("Semicolon seems to be missing");
EXTCONST char PL_warn_reserved[]
EXTCONST char PL_no_aelem[]
INIT("Modification of non-creatable array value attempted, subscript %d");
EXTCONST char PL_no_helem_sv[]
- INIT("Modification of non-creatable hash value attempted, subscript \"%"SVf"\"");
+ INIT("Modification of non-creatable hash value attempted, subscript \"%" SVf "\"");
EXTCONST char PL_no_modify[]
INIT("Modification of a read-only value attempted");
EXTCONST char PL_no_mem[sizeof("Out of memory!\n")]
# ifdef PERLIO_LAYERS
" PERLIO_LAYERS"
# endif
+# ifdef PERL_DEBUG_READONLY_COW
+ " PERL_DEBUG_READONLY_COW"
+# endif
# ifdef PERL_DEBUG_READONLY_OPS
" PERL_DEBUG_READONLY_OPS"
# endif
# ifdef PERL_GLOBAL_STRUCT
" PERL_GLOBAL_STRUCT"
# endif
+# ifdef PERL_GLOBAL_STRUCT_PRIVATE
+ " PERL_GLOBAL_STRUCT_PRIVATE"
+# endif
# ifdef PERL_IMPLICIT_CONTEXT
" PERL_IMPLICIT_CONTEXT"
# endif
# ifdef PERL_IMPLICIT_SYS
" PERL_IMPLICIT_SYS"
# endif
-# ifdef PERL_MAD
- " PERL_MAD"
-# endif
# ifdef PERL_MICRO
" PERL_MICRO"
# endif
# ifdef USE_LOCALE_NUMERIC
" USE_LOCALE_NUMERIC"
# endif
+# ifdef USE_LOCALE_TIME
+ " USE_LOCALE_TIME"
+# endif
# ifdef USE_LONG_DOUBLE
" USE_LONG_DOUBLE"
# endif
# ifdef USE_REENTRANT_API
" USE_REENTRANT_API"
# endif
-# ifdef USE_SFIO
- " USE_SFIO"
-# endif
# ifdef USE_SOCKS
" USE_SOCKS"
# endif
XATTRBLOCK,
XATTRTERM,
XTERMBLOCK,
+ XPOSTDEREF,
XTERMORDORDOR /* evil hack */
/* update exp_name[] in toke.c if adding to this enum */
} expectation;
/* Hints are now stored in a dedicated U32, so the bottom 8 bits are no longer
special and there is no need for HINT_PRIVATE_MASK for COPs
- However, bitops store HINT_INTEGER in their op_private. */
+ However, bitops store HINT_INTEGER in their op_private.
+
+ NOTE: The typical module using these has the bit value hard-coded, so don't
+ blindly change the values of these.
+
+ If we run out of bits, the 2 locale ones could be combined. The PARTIAL one
+ is for "use locale 'FOO'" which excludes some categories. It requires going
+ to %^H to find out which are in and which are out. This could be extended
+ for the normal case of a plain HINT_LOCALE, so that %^H would be used for
+ any locale form. */
#define HINT_INTEGER 0x00000001 /* integer pragma */
#define HINT_STRICT_REFS 0x00000002 /* strict pragma */
#define HINT_LOCALE 0x00000004 /* locale pragma */
#define HINT_BYTES 0x00000008 /* bytes pragma */
-#define HINT_LOCALE_NOT_CHARS 0x00000010 /* locale ':not_characters' pragma */
+#define HINT_LOCALE_PARTIAL 0x00000010 /* locale, but a subset of categories */
#define HINT_EXPLICIT_STRICT_REFS 0x00000020 /* strict.pm */
#define HINT_EXPLICIT_STRICT_SUBS 0x00000040 /* strict.pm */
#if !defined(PERL_FOR_X2P)
# include "embedvar.h"
#endif
-#ifndef PERL_MAD
-# undef PL_madskills
-# undef PL_xmlfp
-# define PL_madskills 0
-# define PL_xmlfp 0
-#endif
/* Now include all the 'global' variables
* If we don't have threads or multiple interpreters
In particular, need the relevant *ish file included already, as it may
define HAVE_INTERP_INTERN */
#include "embed.h"
-#ifndef PERL_MAD
-# undef op_getmad
-# define op_getmad(arg,pegop,slot) NOOP
-#endif
#ifndef PERL_GLOBAL_STRUCT
START_EXTERN_C
#endif
+
+/* if these never got defined, they need defaults */
+#ifndef PERL_SET_CONTEXT
+# define PERL_SET_CONTEXT(i) PERL_SET_INTERP(i)
+#endif
+
+#ifndef PERL_GET_CONTEXT
+# define PERL_GET_CONTEXT PERL_GET_INTERP
+#endif
+
+#ifndef PERL_GET_THX
+# define PERL_GET_THX ((void*)NULL)
+#endif
+
+#ifndef PERL_SET_THX
+# define PERL_SET_THX(t) NOOP
+#endif
+
+
#ifndef PERL_NO_INLINE_FUNCTIONS
/* Static inline funcs that depend on includes and declarations above.
Some of these reference functions in the perl object files, and some
#define PERLDB_SAVESRC_NOSUBS (PL_perldb && (PL_perldb & PERLDBf_SAVESRC_NOSUBS))
#define PERLDB_SAVESRC_INVALID (PL_perldb && (PL_perldb & PERLDBf_SAVESRC_INVALID))
-#ifdef USE_LOCALE_NUMERIC
-
-#define SET_NUMERIC_STANDARD() \
- set_numeric_standard();
-
-#define SET_NUMERIC_LOCAL() \
- set_numeric_local();
-
-/* Returns non-zero If the plain locale pragma without a parameter is in effect
+#ifdef USE_LOCALE
+/* These locale things are all subject to change */
+/* Returns TRUE if the plain locale pragma without a parameter is in effect
*/
-#define IN_LOCALE_RUNTIME (CopHINTS_get(PL_curcop) & HINT_LOCALE)
+# define IN_LOCALE_RUNTIME cBOOL(CopHINTS_get(PL_curcop) & HINT_LOCALE)
-/* Returns non-zero If either form of the locale pragma is in effect */
-#define IN_SOME_LOCALE_FORM_RUNTIME \
- (CopHINTS_get(PL_curcop) & (HINT_LOCALE|HINT_LOCALE_NOT_CHARS))
+/* Returns TRUE if either form of the locale pragma is in effect */
+# define IN_SOME_LOCALE_FORM_RUNTIME \
+ cBOOL(CopHINTS_get(PL_curcop) & (HINT_LOCALE|HINT_LOCALE_PARTIAL))
-#define IN_LOCALE_COMPILETIME (PL_hints & HINT_LOCALE)
-#define IN_SOME_LOCALE_FORM_COMPILETIME \
- (PL_hints & (HINT_LOCALE|HINT_LOCALE_NOT_CHARS))
+# define IN_LOCALE_COMPILETIME cBOOL(PL_hints & HINT_LOCALE)
+# define IN_SOME_LOCALE_FORM_COMPILETIME \
+ cBOOL(PL_hints & (HINT_LOCALE|HINT_LOCALE_PARTIAL))
-#define IN_LOCALE \
+# define IN_LOCALE \
(IN_PERL_COMPILETIME ? IN_LOCALE_COMPILETIME : IN_LOCALE_RUNTIME)
-#define IN_SOME_LOCALE_FORM \
+# define IN_SOME_LOCALE_FORM \
(IN_PERL_COMPILETIME ? IN_SOME_LOCALE_FORM_COMPILETIME \
: IN_SOME_LOCALE_FORM_RUNTIME)
-#define STORE_NUMERIC_LOCAL_SET_STANDARD() \
- bool was_local = PL_numeric_local && IN_LOCALE; \
- if (was_local) SET_NUMERIC_STANDARD();
+# define IN_LC_ALL_COMPILETIME IN_LOCALE_COMPILETIME
+# define IN_LC_ALL_RUNTIME IN_LOCALE_RUNTIME
+
+# define IN_LC_PARTIAL_COMPILETIME cBOOL(PL_hints & HINT_LOCALE_PARTIAL)
+# define IN_LC_PARTIAL_RUNTIME \
+ cBOOL(CopHINTS_get(PL_curcop) & HINT_LOCALE_PARTIAL)
+
+# define IN_LC_COMPILETIME(category) \
+ (IN_LC_ALL_COMPILETIME || (IN_LC_PARTIAL_COMPILETIME \
+ && _is_in_locale_category(TRUE, (category))))
+# define IN_LC_RUNTIME(category) \
+ (IN_LC_ALL_RUNTIME || (IN_LC_PARTIAL_RUNTIME \
+ && _is_in_locale_category(FALSE, (category))))
+# define IN_LC(category) \
+ (IN_LC_COMPILETIME(category) || IN_LC_RUNTIME(category))
+
+#else /* No locale usage */
+# define IN_LOCALE_RUNTIME 0
+# define IN_SOME_LOCALE_FORM_RUNTIME 0
+# define IN_LOCALE_COMPILETIME 0
+# define IN_SOME_LOCALE_FORM_COMPILETIME 0
+# define IN_LOCALE 0
+# define IN_SOME_LOCALE_FORM 0
+# define IN_LC_ALL_COMPILETIME 0
+# define IN_LC_ALL_RUNTIME 0
+# define IN_LC_PARTIAL_COMPILETIME 0
+# define IN_LC_PARTIAL_RUNTIME 0
+# define IN_LC_COMPILETIME(category) 0
+# define IN_LC_RUNTIME(category) 0
+# define IN_LC(category) 0
+#endif
+
+#ifdef USE_LOCALE_NUMERIC
-#define STORE_NUMERIC_STANDARD_SET_LOCAL() \
- bool was_standard = PL_numeric_standard && IN_LOCALE; \
- if (was_standard) SET_NUMERIC_LOCAL();
+/* These macros are for toggling between the underlying locale (LOCAL) and the
+ * C locale. */
+
+/* The first set makes sure that the locale is set to C unless within a 'use
+ * locale's scope; otherwise to the default locale. A function pointer is
+ * used, which can be declared separately by
+ * DECLARATION_FOR_STORE_LC_NUMERIC_SET_TO_NEEDED, followed by the actual
+ * setting (using STORE_LC_NUMERIC_SET_TO_NEEDED()), or the two can be combined
+ * into one call DECLARE_STORE_LC_NUMERIC_SET_TO_NEEDED().
+ * RESTORE_LC_NUMERIC() in all cases restores the locale to what it was before
+ * these were called */
+
+#define _NOT_IN_NUMERIC_STANDARD (! PL_numeric_standard)
+
+/* We can lock the category to stay in the C locale, making requests to the
+ * contrary noops, in the dynamic scope by setting PL_numeric_standard to 2 */
+#define _NOT_IN_NUMERIC_LOCAL (! PL_numeric_local && PL_numeric_standard < 2)
+
+#define DECLARATION_FOR_STORE_LC_NUMERIC_SET_TO_NEEDED \
+ void (*_restore_LC_NUMERIC_function)(pTHX) = NULL;
+
+#define STORE_LC_NUMERIC_SET_TO_NEEDED() \
+ if (IN_LC(LC_NUMERIC)) { \
+ if (_NOT_IN_NUMERIC_LOCAL) { \
+ set_numeric_local(); \
+ _restore_LC_NUMERIC_function = &Perl_set_numeric_standard; \
+ } \
+ } \
+ else { \
+ if (_NOT_IN_NUMERIC_STANDARD) { \
+ SET_NUMERIC_STANDARD(); \
+ _restore_LC_NUMERIC_function = &Perl_set_numeric_local; \
+ } \
+ }
+
+#define DECLARE_STORE_LC_NUMERIC_SET_TO_NEEDED() \
+ DECLARATION_FOR_STORE_LC_NUMERIC_SET_TO_NEEDED; \
+ STORE_LC_NUMERIC_SET_TO_NEEDED();
+
+#define RESTORE_LC_NUMERIC() \
+ if (_restore_LC_NUMERIC_function) { \
+ _restore_LC_NUMERIC_function(aTHX); \
+ }
+
+/* The next two macros set unconditionally. These should be rarely used, and
+ * only after being sure that this is what is needed */
+#define SET_NUMERIC_STANDARD() \
+ STMT_START { if (_NOT_IN_NUMERIC_STANDARD) set_numeric_standard(); \
+ } STMT_END
+
+#define SET_NUMERIC_LOCAL() \
+ STMT_START { if (_NOT_IN_NUMERIC_LOCAL) \
+ set_numeric_local(); } STMT_END
+
+/* The rest of these LC_NUMERIC macros toggle to one or the other state, with
+ * the RESTORE_foo ones called to switch back, but only if need be */
+#define STORE_NUMERIC_LOCAL_SET_STANDARD() \
+ bool _was_local = _NOT_IN_NUMERIC_STANDARD; \
+ if (_was_local) set_numeric_standard();
+
+/* Doesn't change to underlying locale unless within the scope of some form of
+ * 'use locale'. This is the usual desired behavior. */
+#define STORE_NUMERIC_STANDARD_SET_LOCAL() \
+ bool _was_standard = _NOT_IN_NUMERIC_LOCAL \
+ && IN_LC(LC_NUMERIC); \
+ if (_was_standard) set_numeric_local();
+
+/* Rarely, we want to change to the underlying locale even outside of 'use
+ * locale'. This is principally in the POSIX:: functions */
+#define STORE_NUMERIC_STANDARD_FORCE_LOCAL() \
+ bool _was_standard = _NOT_IN_NUMERIC_LOCAL; \
+ if (_was_standard) set_numeric_local();
+
+/* Lock to the C locale until unlock is called */
+#define LOCK_NUMERIC_STANDARD() \
+ (__ASSERT_(PL_numeric_standard) \
+ PL_numeric_standard = 2)
+
+#define UNLOCK_NUMERIC_STANDARD() \
+ (__ASSERT_(PL_numeric_standard == 2) \
+ PL_numeric_standard = 1)
#define RESTORE_NUMERIC_LOCAL() \
- if (was_local) SET_NUMERIC_LOCAL();
+ if (_was_local) set_numeric_local();
#define RESTORE_NUMERIC_STANDARD() \
- if (was_standard) SET_NUMERIC_STANDARD();
+ if (_was_standard) SET_NUMERIC_STANDARD();
#define Atof my_atof
#define IS_NUMERIC_RADIX(a, b) (0)
#define STORE_NUMERIC_LOCAL_SET_STANDARD() /**/
#define STORE_NUMERIC_STANDARD_SET_LOCAL() /**/
+#define STORE_NUMERIC_STANDARD_FORCE_LOCAL()
#define RESTORE_NUMERIC_LOCAL() /**/
#define RESTORE_NUMERIC_STANDARD() /**/
+#define DECLARATION_FOR_STORE_LC_NUMERIC_SET_TO_NEEDED
+#define STORE_LC_NUMERIC_SET_TO_NEEDED()
+#define DECLARE_STORE_LC_NUMERIC_SET_TO_NEEDED()
+#define RESTORE_LC_NUMERIC()
+#define LOCK_NUMERIC_STANDARD()
+#define UNLOCK_NUMERIC_STANDARD()
+
#define Atof my_atof
-#define IN_LOCALE_RUNTIME 0
-#define IN_LOCALE_COMPILETIME 0
#endif /* !USE_LOCALE_NUMERIC */
# define Atoul(s) Strtoul(s, NULL, 10)
#endif
-
-/* if these never got defined, they need defaults */
-#ifndef PERL_SET_CONTEXT
-# define PERL_SET_CONTEXT(i) PERL_SET_INTERP(i)
-#endif
-
-#ifndef PERL_GET_CONTEXT
-# define PERL_GET_CONTEXT PERL_GET_INTERP
-#endif
-
-#ifndef PERL_GET_THX
-# define PERL_GET_THX ((void*)NULL)
-#endif
-
-#ifndef PERL_SET_THX
-# define PERL_SET_THX(t) NOOP
-#endif
-
#ifndef PERL_SCRIPT_MODE
#define PERL_SCRIPT_MODE "r"
#endif
#ifndef PERL_MICRO
# ifndef PERL_ASYNC_CHECK
-# define PERL_ASYNC_CHECK() if (PL_sig_pending) PL_signalhook(aTHX)
+# define PERL_ASYNC_CHECK() if (UNLIKELY(PL_sig_pending)) PL_signalhook(aTHX)
# endif
#endif
#endif
#if O_TEXT != O_BINARY
- /* If you have different O_TEXT and O_BINARY and you are a CLRF shop,
+ /* If you have different O_TEXT and O_BINARY and you are a CRLF shop,
* that is, you are somehow DOSish. */
# if defined(__HAIKU__) || defined(__VOS__) || defined(__CYGWIN__)
/* Haiku has O_TEXT != O_BINARY but O_TEXT and O_BINARY have no effect;
#define IS_NUMBER_NEG 0x08 /* leading minus sign */
#define IS_NUMBER_INFINITY 0x10 /* this is big */
#define IS_NUMBER_NAN 0x20 /* this is not */
+#define IS_NUMBER_TRAILING 0x40 /* number has trailing trash */
#define GROK_NUMERIC_RADIX(sp, send) grok_numeric_radix(sp, send)
#define PERL_SCAN_SILENT_ILLDIGIT 0x04 /* grok_??? not warn about illegal digits */
#define PERL_SCAN_SILENT_NON_PORTABLE 0x08 /* grok_??? not warn about very large
numbers which are <= UV_MAX */
+#define PERL_SCAN_TRAILING 0x10 /* grok_number_flags() allow trailing
+ and set IS_NUMBER_TRAILING */
+
/* Output flags: */
#define PERL_SCAN_GREATER_THAN_UV_MAX 0x02 /* should this merge with above? */
#define PERL_PV_ESCAPE_NOCLEAR 0x4000
#define PERL_PV_ESCAPE_RE 0x8000
+#define PERL_PV_ESCAPE_DWIM 0x10000
+
#define PERL_PV_PRETTY_NOCLEAR PERL_PV_ESCAPE_NOCLEAR
/* used by pv_display in dump.c*/