This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Add HAS_STRTOD_L to metaconfig.h and rebuild Configure
[perl5.git] / handy.h
diff --git a/handy.h b/handy.h
index 77415ec..9ba05de 100644 (file)
--- a/handy.h
+++ b/handy.h
@@ -165,54 +165,11 @@ typedef U16TYPE U16;
 typedef I32TYPE I32;
 typedef U32TYPE U32;
 
-#ifdef HAS_QUAD
+#ifdef QUADKIND
 typedef I64TYPE I64;
 typedef U64TYPE U64;
 #endif
 
-/* INT64_C/UINT64_C are C99 from <stdint.h> (so they will not be
- * available in strict C89 mode), but they are nice, so let's define
- * them if necessary. */
-#if defined(HAS_QUAD)
-#  undef PeRl_INT64_C
-#  undef PeRl_UINT64_C
-/* Prefer the native integer types (int and long) over long long
- * (which is not C89) and Win32-specific __int64. */
-#  if QUADKIND == QUAD_IS_INT && INTSIZE == 8
-#    define PeRl_INT64_C(c)    (c)
-#    define PeRl_UINT64_C(c)   CAT2(c,U)
-#  endif
-#  if QUADKIND == QUAD_IS_LONG && LONGSIZE == 8
-#    define PeRl_INT64_C(c)    CAT2(c,L)
-#    define PeRl_UINT64_C(c)   CAT2(c,UL)
-#  endif
-#  if QUADKIND == QUAD_IS_LONG_LONG && defined(HAS_LONG_LONG)
-#    define PeRl_INT64_C(c)    CAT2(c,LL)
-#    define PeRl_UINT64_C(c)   CAT2(c,ULL)
-#  endif
-#  if QUADKIND == QUAD_IS___INT64
-#    define PeRl_INT64_C(c)    CAT2(c,I64)
-#    define PeRl_UINT64_C(c)   CAT2(c,UI64)
-#  endif
-#  ifndef PeRl_INT64_C
-#    define PeRl_INT64_C(c)    ((I64)(c)) /* last resort */
-#    define PeRl_UINT64_C(c)   ((U64)(c))
-#  endif
-/* In OS X the INT64_C/UINT64_C are defined with LL/ULL, which will
- * not fly with C89-pedantic gcc, so let's undefine them first so that
- * we can redefine them with our native integer preferring versions. */
-#  if defined(PERL_DARWIN) && defined(PERL_GCC_PEDANTIC)
-#    undef INT64_C
-#    undef UINT64_C
-#  endif
-#  ifndef INT64_C
-#    define INT64_C(c) PeRl_INT64_C(c)
-#  endif
-#  ifndef UINT64_C
-#    define UINT64_C(c) PeRl_UINT64_C(c)
-#  endif
-#endif
-
 #if defined(UINT8_MAX) && defined(INT16_MAX) && defined(INT32_MAX)
 
 /* I8_MAX and I8_MIN constants are not defined, as I8 is an ambiguous type.
@@ -260,6 +217,26 @@ typedef U64TYPE U64;
 
 #endif
 
+/* These C99 typedefs are useful sometimes for, say, loop variables whose
+ * maximum values are small, but for which speed trumps size.  If we have a C99
+ * compiler, use that.  Otherwise, a plain 'int' should be good enough.
+ *
+ * Restrict these to core for now until we are more certain this is a good
+ * idea. */
+#if defined(PERL_CORE) || defined(PERL_EXT)
+#  ifdef I_STDINT
+    typedef  int_fast8_t  PERL_INT_FAST8_T;
+    typedef uint_fast8_t  PERL_UINT_FAST8_T;
+    typedef  int_fast16_t PERL_INT_FAST16_T;
+    typedef uint_fast16_t PERL_UINT_FAST16_T;
+#  else
+    typedef int           PERL_INT_FAST8_T;
+    typedef unsigned int  PERL_UINT_FAST8_T;
+    typedef int           PERL_INT_FAST16_T;
+    typedef unsigned int  PERL_UINT_FAST16_T;
+#  endif
+#endif
+
 /* log(2) (i.e., log base 10 of 2) is pretty close to 0.30103, just in case
  * anyone is grepping for it */
 #define BIT_DIGITS(N)   (((N)*146)/485 + 1)  /* log10(2) =~ 146/485 */
@@ -296,78 +273,78 @@ typedef U64TYPE U64;
 /*
 =head1 SV-Body Allocation
 
-=for apidoc Ama|SV*|newSVpvs|const char* s
-Like C<newSVpvn>, but takes a C<NUL>-terminated literal string instead of a
+=for apidoc Ama|SV*|newSVpvs|"literal string" s
+Like C<newSVpvn>, but takes a literal string instead of a
 string/length pair.
 
-=for apidoc Ama|SV*|newSVpvs_flags|const char* s|U32 flags
-Like C<newSVpvn_flags>, but takes a C<NUL>-terminated literal string instead of
+=for apidoc Ama|SV*|newSVpvs_flags|"literal string" s|U32 flags
+Like C<newSVpvn_flags>, but takes a literal string instead of
 a string/length pair.
 
-=for apidoc Ama|SV*|newSVpvs_share|const char* s
-Like C<newSVpvn_share>, but takes a C<NUL>-terminated literal string instead of
+=for apidoc Ama|SV*|newSVpvs_share|"literal string" s
+Like C<newSVpvn_share>, but takes a literal string instead of
 a string/length pair and omits the hash parameter.
 
-=for apidoc Am|void|sv_catpvs_flags|SV* sv|const char* s|I32 flags
-Like C<sv_catpvn_flags>, but takes a C<NUL>-terminated literal string instead
+=for apidoc Am|void|sv_catpvs_flags|SV* sv|"literal string" s|I32 flags
+Like C<sv_catpvn_flags>, but takes a literal string instead
 of a string/length pair.
 
-=for apidoc Am|void|sv_catpvs_nomg|SV* sv|const char* s
-Like C<sv_catpvn_nomg>, but takes a C<NUL>-terminated literal string instead of
+=for apidoc Am|void|sv_catpvs_nomg|SV* sv|"literal string" s
+Like C<sv_catpvn_nomg>, but takes a literal string instead of
 a string/length pair.
 
-=for apidoc Am|void|sv_catpvs|SV* sv|const char* s
-Like C<sv_catpvn>, but takes a C<NUL>-terminated literal string instead of a
+=for apidoc Am|void|sv_catpvs|SV* sv|"literal string" s
+Like C<sv_catpvn>, but takes a literal string instead of a
 string/length pair.
 
-=for apidoc Am|void|sv_catpvs_mg|SV* sv|const char* s
-Like C<sv_catpvn_mg>, but takes a C<NUL>-terminated literal string instead of a
+=for apidoc Am|void|sv_catpvs_mg|SV* sv|"literal string" s
+Like C<sv_catpvn_mg>, but takes a literal string instead of a
 string/length pair.
 
-=for apidoc Am|void|sv_setpvs|SV* sv|const char* s
-Like C<sv_setpvn>, but takes a C<NUL>-terminated literal string instead of a
+=for apidoc Am|void|sv_setpvs|SV* sv|"literal string" s
+Like C<sv_setpvn>, but takes a literal string instead of a
 string/length pair.
 
-=for apidoc Am|void|sv_setpvs_mg|SV* sv|const char* s
-Like C<sv_setpvn_mg>, but takes a C<NUL>-terminated literal string instead of a
+=for apidoc Am|void|sv_setpvs_mg|SV* sv|"literal string" s
+Like C<sv_setpvn_mg>, but takes a literal string instead of a
 string/length pair.
 
-=for apidoc Am|SV *|sv_setref_pvs|const char* s
-Like C<sv_setref_pvn>, but takes a C<NUL>-terminated literal string instead of
+=for apidoc Am|SV *|sv_setref_pvs|"literal string" s
+Like C<sv_setref_pvn>, but takes a literal string instead of
 a string/length pair.
 
 =head1 Memory Management
 
-=for apidoc Ama|char*|savepvs|const char* s
-Like C<savepvn>, but takes a C<NUL>-terminated literal string instead of a
+=for apidoc Ama|char*|savepvs|"literal string" s
+Like C<savepvn>, but takes a literal string instead of a
 string/length pair.
 
-=for apidoc Ama|char*|savesharedpvs|const char* s
+=for apidoc Ama|char*|savesharedpvs|"literal string" s
 A version of C<savepvs()> which allocates the duplicate string in memory
 which is shared between threads.
 
 =head1 GV Functions
 
-=for apidoc Am|HV*|gv_stashpvs|const char* name|I32 create
-Like C<gv_stashpvn>, but takes a C<NUL>-terminated literal string instead of a
+=for apidoc Am|HV*|gv_stashpvs|"literal string" name|I32 create
+Like C<gv_stashpvn>, but takes a literal string instead of a
 string/length pair.
 
 =head1 Hash Manipulation Functions
 
-=for apidoc Am|SV**|hv_fetchs|HV* tb|const char* key|I32 lval
-Like C<hv_fetch>, but takes a C<NUL>-terminated literal string instead of a
+=for apidoc Am|SV**|hv_fetchs|HV* tb|"literal string" key|I32 lval
+Like C<hv_fetch>, but takes a literal string instead of a
 string/length pair.
 
-=for apidoc Am|SV**|hv_stores|HV* tb|const char* key|NULLOK SV* val
-Like C<hv_store>, but takes a C<NUL>-terminated literal string instead of a
+=for apidoc Am|SV**|hv_stores|HV* tb|"literal string" key|SV* val
+Like C<hv_store>, but takes a literal string instead of a
 string/length pair
 and omits the hash parameter.
 
 =head1 Lexer interface
 
-=for apidoc Amx|void|lex_stuff_pvs|const char *pv|U32 flags
+=for apidoc Amx|void|lex_stuff_pvs|"literal string" pv|U32 flags
 
-Like L</lex_stuff_pvn>, but takes a C<NUL>-terminated literal string instead of
+Like L</lex_stuff_pvn>, but takes a literal string instead of
 a string/length pair.
 
 =cut
@@ -1082,11 +1059,9 @@ patched there.  The file as of this writing is cpan/Devel-PPPort/parts/inc/misc
 
 */
 
-/* Specify the widest unsigned type on the platform.  Use U64TYPE because U64
- * is known only in the perl core, and this macro can be called from outside
- * that */
-#ifdef HAS_QUAD
-#   define WIDEST_UTYPE U64TYPE
+/* Specify the widest unsigned type on the platform. */
+#ifdef QUADKIND
+#   define WIDEST_UTYPE U64
 #else
 #   define WIDEST_UTYPE U32
 #endif
@@ -1150,7 +1125,13 @@ patched there.  The file as of this writing is cpan/Devel-PPPort/parts/inc/misc
  *
  * The first group of these is ordered in what I (khw) estimate to be the
  * frequency of their use.  This gives a slight edge to exiting a loop earlier
- * (in reginclass() in regexec.c) */
+ * (in reginclass() in regexec.c).  Except \v should be last, as it isn't a
+ * real Posix character class, and some (small) inefficiencies in regular
+ * expression handling would be introduced by putting it in the middle of those
+ * that are.  Also, cntrl and ascii come after the others as it may be useful
+ * to group these which have no members that match above Latin1, (or above
+ * ASCII in the latter case) */
+
 #  define _CC_WORDCHAR           0      /* \w and [:word:] */
 #  define _CC_DIGIT              1      /* \d and [:digit:] */
 #  define _CC_ALPHA              2      /* [:alpha:] */
@@ -1161,17 +1142,6 @@ patched there.  The file as of this writing is cpan/Devel-PPPort/parts/inc/misc
 #  define _CC_ALPHANUMERIC       7      /* [:alnum:] */
 #  define _CC_GRAPH              8      /* [:graph:] */
 #  define _CC_CASED              9      /* [:lower:] or [:upper:] under /i */
-
-#define _FIRST_NON_SWASH_CC     10
-/* The character classes above are implemented with swashes.  The second group
- * (just below) contains the ones implemented without.  These are also sorted
- * in rough order of the frequency of their use, except that \v should be last,
- * as it isn't a real Posix character class, and some (small) inefficiencies in
- * regular expression handling would be introduced by putting it in the middle
- * of those that are.  Also, cntrl and ascii come after the others as it may be
- * useful to group these which have no members that match above Latin1, (or
- * above ASCII in the latter case) */
-
 #  define _CC_SPACE             10      /* \s, [:space:] */
 #  define _CC_PSXSPC            _CC_SPACE   /* XXX Temporary, can be removed
                                                when the deprecated isFOO_utf8()
@@ -1238,36 +1208,8 @@ typedef enum {
 } _char_class_number;
 #endif
 
-#define POSIX_SWASH_COUNT _FIRST_NON_SWASH_CC
 #define POSIX_CC_COUNT    (_HIGHEST_REGCOMP_DOT_H_SYNC + 1)
 
-#if defined(PERL_IN_UTF8_C)                         \
- || defined(PERL_IN_REGCOMP_C)                      \
- || defined(PERL_IN_REGEXEC_C)
-#   if _CC_WORDCHAR != 0 || _CC_DIGIT != 1 || _CC_ALPHA != 2 || _CC_LOWER != 3 \
-       || _CC_UPPER != 4 || _CC_PUNCT != 5 || _CC_PRINT != 6                   \
-       || _CC_ALPHANUMERIC != 7 || _CC_GRAPH != 8 || _CC_CASED != 9
-      #error Need to adjust order of swash_property_names[]
-#   endif
-
-/* This is declared static in each of the few files that this is #defined for
- * to keep them from being publicly accessible.  Hence there is a small amount
- * of wasted space */
-
-static const char* const swash_property_names[] = {
-    "XPosixWord",
-    "XPosixDigit",
-    "XPosixAlpha",
-    "XPosixLower",
-    "XPosixUpper",
-    "XPosixPunct",
-    "XPosixPrint",
-    "XPosixAlnum",
-    "XPosixGraph",
-    "Cased"
-};
-#endif
-
 START_EXTERN_C
 #  ifdef DOINIT
 EXTCONST  U32 PL_charclass[] = {
@@ -2344,6 +2286,11 @@ PoisonWith(0xEF) for catching access to freed memory.
        (void)(UNLIKELY(_MEM_WRAP_WILL_WRAP(n,t)) \
        && (Perl_croak_nocontext("%s",(a)),0))
 
+/* "a" arg must be a string literal */
+#  define MEM_WRAP_CHECK_s(n,t,a) \
+       (void)(UNLIKELY(_MEM_WRAP_WILL_WRAP(n,t)) \
+       && (Perl_croak_nocontext("" a ""),0))
+
 #define MEM_WRAP_CHECK_(n,t) MEM_WRAP_CHECK(n,t),
 
 #define PERL_STRLEN_ROUNDUP(n) ((void)(((n) > MEM_SIZE_MAX - 2 * PERL_STRLEN_ROUNDUP_QUANTUM) ? (croak_memory_wrap(),0) : 0), _PERL_STRLEN_ROUNDUP_UNCHECKED(n))
@@ -2351,7 +2298,7 @@ PoisonWith(0xEF) for catching access to freed memory.
 
 #define MEM_WRAP_CHECK(n,t)
 #define MEM_WRAP_CHECK_1(n,t,a)
-#define MEM_WRAP_CHECK_2(n,t,a,b)
+#define MEM_WRAP_CHECK_s(n,t,a)
 #define MEM_WRAP_CHECK_(n,t)
 
 #define PERL_STRLEN_ROUNDUP(n) _PERL_STRLEN_ROUNDUP_UNCHECKED(n)
@@ -2448,6 +2395,9 @@ void Perl_mem_log_del_sv(const SV *sv, const char *filename, const int linenumbe
 #define Safefree(d)    safefree(MEM_LOG_FREE((Malloc_t)(d)))
 #endif
 
+/* assert that a valid ptr has been supplied - use this instead of assert(ptr)  *
+ * as it handles cases like constant string arguments without throwing warnings *
+ * the cast is required, as is the inequality check, to avoid warnings          */
 #define perl_assert_ptr(p) assert( ((void*)(p)) != 0 )
 
 
@@ -2455,6 +2405,7 @@ void Perl_mem_log_del_sv(const SV *sv, const char *filename, const int linenumbe
 #define Copy(s,d,n,t)  (MEM_WRAP_CHECK_(n,t) perl_assert_ptr(d), perl_assert_ptr(s), (void)memcpy((char*)(d),(const char*)(s), (n) * sizeof(t)))
 #define Zero(d,n,t)    (MEM_WRAP_CHECK_(n,t) perl_assert_ptr(d), (void)memzero((char*)(d), (n) * sizeof(t)))
 
+/* Like above, but returns a pointer to 'd' */
 #define MoveD(s,d,n,t) (MEM_WRAP_CHECK_(n,t) perl_assert_ptr(d), perl_assert_ptr(s), memmove((char*)(d),(const char*)(s), (n) * sizeof(t)))
 #define CopyD(s,d,n,t) (MEM_WRAP_CHECK_(n,t) perl_assert_ptr(d), perl_assert_ptr(s), memcpy((char*)(d),(const char*)(s), (n) * sizeof(t)))
 #define ZeroD(d,n,t)   (MEM_WRAP_CHECK_(n,t) perl_assert_ptr(d), memzero((char*)(d), (n) * sizeof(t)))