X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/b7112dce7ec5b90ace89fcf4598b0be8168fea82..bf634d4e041c3abb5408cd1f18f1c18d298012d1:/handy.h diff --git a/handy.h b/handy.h index d8d041d..9ba05de 100644 --- 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 (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, but takes a C-terminated literal string instead of a +=for apidoc Ama|SV*|newSVpvs|"literal string" s +Like C, but takes a literal string instead of a string/length pair. -=for apidoc Ama|SV*|newSVpvs_flags|const char* s|U32 flags -Like C, but takes a C-terminated literal string instead of +=for apidoc Ama|SV*|newSVpvs_flags|"literal string" s|U32 flags +Like C, but takes a literal string instead of a string/length pair. -=for apidoc Ama|SV*|newSVpvs_share|const char* s -Like C, but takes a C-terminated literal string instead of +=for apidoc Ama|SV*|newSVpvs_share|"literal string" s +Like C, 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, but takes a C-terminated literal string instead +=for apidoc Am|void|sv_catpvs_flags|SV* sv|"literal string" s|I32 flags +Like C, 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, but takes a C-terminated literal string instead of +=for apidoc Am|void|sv_catpvs_nomg|SV* sv|"literal string" s +Like C, but takes a literal string instead of a string/length pair. -=for apidoc Am|void|sv_catpvs|SV* sv|const char* s -Like C, but takes a C-terminated literal string instead of a +=for apidoc Am|void|sv_catpvs|SV* sv|"literal string" s +Like C, 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, but takes a C-terminated literal string instead of a +=for apidoc Am|void|sv_catpvs_mg|SV* sv|"literal string" s +Like C, but takes a literal string instead of a string/length pair. -=for apidoc Am|void|sv_setpvs|SV* sv|const char* s -Like C, but takes a C-terminated literal string instead of a +=for apidoc Am|void|sv_setpvs|SV* sv|"literal string" s +Like C, 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, but takes a C-terminated literal string instead of a +=for apidoc Am|void|sv_setpvs_mg|SV* sv|"literal string" s +Like C, but takes a literal string instead of a string/length pair. -=for apidoc Am|SV *|sv_setref_pvs|const char* s -Like C, but takes a C-terminated literal string instead of +=for apidoc Am|SV *|sv_setref_pvs|"literal string" s +Like C, but takes a literal string instead of a string/length pair. =head1 Memory Management -=for apidoc Ama|char*|savepvs|const char* s -Like C, but takes a C-terminated literal string instead of a +=for apidoc Ama|char*|savepvs|"literal string" s +Like C, 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 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, but takes a C-terminated literal string instead of a +=for apidoc Am|HV*|gv_stashpvs|"literal string" name|I32 create +Like C, 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, but takes a C-terminated literal string instead of a +=for apidoc Am|SV**|hv_fetchs|HV* tb|"literal string" key|I32 lval +Like C, 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, but takes a C-terminated literal string instead of a +=for apidoc Am|SV**|hv_stores|HV* tb|"literal string" key|SV* val +Like C, 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, but takes a C-terminated literal string instead of +Like L, 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[] = { @@ -2312,7 +2254,8 @@ PoisonWith(0xEF) for catching access to freed memory. */ # define _MEM_WRAP_NEEDS_RUNTIME_CHECK(n,t) \ - (8 * sizeof(n) + sizeof(t) > sizeof(MEM_SIZE)) + ( sizeof(MEM_SIZE) < sizeof(n) \ + || sizeof(t) > ((MEM_SIZE)1 << 8*(sizeof(MEM_SIZE) - sizeof(n)))) /* This is written in a slightly odd way to avoid various spurious * compiler warnings. We *want* to write the expression as @@ -2343,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)) @@ -2350,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) @@ -2447,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 ) @@ -2454,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)))