X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/1a0901dbc900e43ec8a4a9d55385b089d2733473..f1d34ca8c42df1cea97652592d84d9a587312c74:/handy.h diff --git a/handy.h b/handy.h index 00bc5e4..c670398 100644 --- a/handy.h +++ b/handy.h @@ -1,7 +1,7 @@ /* handy.h * * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000, - * 2001, 2002, 2004, 2005, 2006, 2007, 2008 by Larry Wall and others + * 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2012 by Larry Wall and others * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -12,11 +12,7 @@ #ifdef NULL #undef NULL #endif -#ifndef I286 # define NULL 0 -#else -# define NULL 0L -#endif #endif #ifndef PERL_CORE @@ -70,10 +66,13 @@ Null SV pointer. (No longer available when C is defined.) #define MUTABLE_IO(p) ((IO *)MUTABLE_PTR(p)) #define MUTABLE_SV(p) ((SV *)MUTABLE_PTR(p)) -/* XXX Configure ought to have a test for a boolean type, if I can - just figure out all the headers such a test needs. - Andy Dougherty August 1996 -*/ +#ifdef I_STDBOOL +# include +# ifndef HAS_BOOL +# define HAS_BOOL 1 +# endif +#endif + /* bool is built-in for g++-2.6.3 and later, which might be used for extensions. <_G_config.h> defines _G_HAVE_BOOL, but we can't be sure _G_config.h will be included before this file. _G_config.h @@ -102,7 +101,7 @@ Null SV pointer. (No longer available when C is defined.) #endif /* NeXT || __NeXT__ */ #ifndef HAS_BOOL -# if defined(UTS) || defined(VMS) +# if defined(VMS) # define bool int # else # define bool char @@ -112,9 +111,10 @@ Null SV pointer. (No longer available when C is defined.) /* a simple (bool) cast may not do the right thing: if bool is defined * as char for example, then the cast from int is implementation-defined + * (bool)!!(cbool) in a ternary triggers a bug in xlc on AIX */ -#define cBOOL(cbool) ((bool)!!(cbool)) +#define cBOOL(cbool) ((cbool) ? (bool)1 : (bool)0) /* Try to figure out __func__ or __FUNCTION__ equivalent, if any. * XXX Should really be a Configure probe, with HAS__FUNCTION__ @@ -123,7 +123,7 @@ Null SV pointer. (No longer available when C is defined.) #if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (defined(__SUNPRO_C)) /* C99 or close enough. */ # define FUNCTION__ __func__ #else -# if (defined(_MSC_VER) && _MSC_VER < 1300) || /* Pre-MSVC 7.0 has neither __func__ nor __FUNCTION and no good workarounds, either. */ \ +# if (defined(_MSC_VER) && _MSC_VER < 1300) || /* MSVC6 has neither __func__ nor __FUNCTION and no good workarounds, either. */ \ (defined(__DECC_VER)) /* Tru64 or VMS, and strict C89 being used, but not modern enough cc (in Tur64, -c99 not known, only -std1). */ # define FUNCTION__ "" # else @@ -187,40 +187,31 @@ typedef U64TYPE U64; #endif /* PERL_CORE */ #if defined(HAS_QUAD) && defined(USE_64_BIT_INT) -# ifndef UINT64_C /* usually from */ -# if defined(HAS_LONG_LONG) && QUADKIND == QUAD_IS_LONG_LONG -# define INT64_C(c) CAT2(c,LL) -# define UINT64_C(c) CAT2(c,ULL) +# if defined(HAS_LONG_LONG) && QUADKIND == QUAD_IS_LONG_LONG +# define PeRl_INT64_C(c) CAT2(c,LL) +# define PeRl_UINT64_C(c) CAT2(c,ULL) +# else +# if QUADKIND == QUAD_IS___INT64 +# define PeRl_INT64_C(c) CAT2(c,I64) +# define PeRl_UINT64_C(c) CAT2(c,UI64) # else # if LONGSIZE == 8 && QUADKIND == QUAD_IS_LONG -# define INT64_C(c) CAT2(c,L) -# define UINT64_C(c) CAT2(c,UL) +# define PeRl_INT64_C(c) CAT2(c,L) +# define PeRl_UINT64_C(c) CAT2(c,UL) # else -# if defined(_WIN64) && defined(_MSC_VER) -# define INT64_C(c) CAT2(c,I64) -# define UINT64_C(c) CAT2(c,UI64) -# else -# define INT64_C(c) ((I64TYPE)(c)) -# define UINT64_C(c) ((U64TYPE)(c)) -# endif +# define PeRl_INT64_C(c) ((I64TYPE)(c)) +# define PeRl_UINT64_C(c) ((U64TYPE)(c)) # endif # endif # endif +# ifndef UINT64_C +# define UINT64_C(c) PeRl_UINT64_C(c) +# endif +# ifndef INT64_C +# define INT64_C(c) PeRl_INT64_C(c) +# endif #endif -/* HMB H.Merijn Brand - a placeholder for preparing Configure patches: - * - * USE_DTRACE HAS_PSEUDOFORK HAS_TIMEGM LOCALTIME_R_NEEDS_TZSET - * GMTIME_MAX GMTIME_MIN LOCALTIME_MAX LOCALTIME_MIN - * HAS_CTIME64 HAS_LOCALTIME64 HAS_GMTIME64 HAS_DIFFTIME64 - * HAS_MKTIME64 HAS_ASCTIME64 HAS_GETADDRINFO HAS_GETNAMEINFO - * HAS_INETNTOP HAS_INETPTON CHARBITS HAS_PRCTL - * Not (yet) used at top level, but mention them for metaconfig - */ - -/* Mention I8SIZE, U8SIZE, I16SIZE, U16SIZE, I32SIZE, U32SIZE, - I64SIZE, and U64SIZE here so that metaconfig pulls them in. */ - #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. @@ -289,17 +280,41 @@ pair. 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 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 literal string instead of a +string/length pair. + =for apidoc Am|void|sv_catpvs|SV* sv|const char* 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 literal string instead of a +string/length pair. + =for apidoc Am|void|sv_setpvs|SV* sv|const char* 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 literal string instead of a +string/length pair. + +=for apidoc Am|SV *|sv_setref_pvs|const char* 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 literal string instead of a string/length pair. +=for apidoc Ama|char*|savesharedpvs|const char* 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 @@ -337,11 +352,28 @@ string/length pair. #define newSVpvs_flags(str,flags) \ Perl_newSVpvn_flags(aTHX_ STR_WITH_LEN(str), flags) #define newSVpvs_share(str) Perl_newSVpvn_share(aTHX_ STR_WITH_LEN(str), 0) -#define sv_catpvs(sv, str) Perl_sv_catpvn_flags(aTHX_ sv, STR_WITH_LEN(str), SV_GMAGIC) +#define sv_catpvs_flags(sv, str, flags) \ + Perl_sv_catpvn_flags(aTHX_ sv, STR_WITH_LEN(str), flags) +#define sv_catpvs_nomg(sv, str) \ + Perl_sv_catpvn_flags(aTHX_ sv, STR_WITH_LEN(str), 0) +#define sv_catpvs(sv, str) \ + Perl_sv_catpvn_flags(aTHX_ sv, STR_WITH_LEN(str), SV_GMAGIC) +#define sv_catpvs_mg(sv, str) \ + Perl_sv_catpvn_flags(aTHX_ sv, STR_WITH_LEN(str), SV_GMAGIC|SV_SMAGIC) #define sv_setpvs(sv, str) Perl_sv_setpvn(aTHX_ sv, STR_WITH_LEN(str)) +#define sv_setpvs_mg(sv, str) Perl_sv_setpvn_mg(aTHX_ sv, STR_WITH_LEN(str)) +#define sv_setref_pvs(rv, classname, str) \ + Perl_sv_setref_pvn(aTHX_ rv, classname, STR_WITH_LEN(str)) #define savepvs(str) Perl_savepvn(aTHX_ STR_WITH_LEN(str)) -#define gv_stashpvs(str, create) Perl_gv_stashpvn(aTHX_ STR_WITH_LEN(str), create) -#define gv_fetchpvs(namebeg, add, sv_type) Perl_gv_fetchpvn_flags(aTHX_ STR_WITH_LEN(namebeg), add, sv_type) +#define savesharedpvs(str) Perl_savesharedpvn(aTHX_ STR_WITH_LEN(str)) +#define gv_stashpvs(str, create) \ + Perl_gv_stashpvn(aTHX_ STR_WITH_LEN(str), create) +#define gv_fetchpvs(namebeg, add, sv_type) \ + Perl_gv_fetchpvn_flags(aTHX_ STR_WITH_LEN(namebeg), add, sv_type) +#define gv_fetchpvn(namebeg, len, add, sv_type) \ + Perl_gv_fetchpvn_flags(aTHX_ namebeg, len, add, sv_type) +#define sv_catxmlpvs(dsv, str, utf8) \ + Perl_sv_catxmlpvn(aTHX_ dsv, STR_WITH_LEN(str), utf8) #define hv_fetchs(hv,key,lval) \ ((SV **)Perl_hv_common(aTHX_ (hv), NULL, STR_WITH_LEN(key), 0, \ (lval) ? (HV_FETCH_JUST_SV | HV_FETCH_LVALUE) \ @@ -438,41 +470,81 @@ C). /* =head1 Character classes -The functions in this section operate using the character set of the platform -Perl is running on, and are unaffected by locale. For ASCII platforms, they -will all return false for characters outside the ASCII range. For EBCDIC -platforms, they use the code page of the platform. The code pages that Perl -knows about all have 8-bit characters, so most of these functions will return -true for more characters than on ASCII platforms. - -=for apidoc Am|bool|isALNUM|char ch -Returns a boolean indicating whether the C C is an -alphanumeric character (including underscore) or digit in the platform's native -character set. +There are three variants for all the functions in this section. The base ones +operate using the character set of the platform Perl is running on. The ones +with an C<_A> suffix operate on the ASCII character set, and the ones with an +C<_L1> suffix operate on the full Latin1 character set. All are unaffected by +locale and by C. + +For ASCII platforms, the base function with no suffix and the one with the +C<_A> suffix are identical. The function with the C<_L1> suffix imposes the +Latin-1 character set onto the platform. That is, the code points that are +ASCII are unaffected, since ASCII is a subset of Latin-1. But the non-ASCII +code points are treated as if they are Latin-1 characters. For example, +C will return true when called with the code point 0xA0, which is +the Latin-1 NO-BREAK SPACE. + +For EBCDIC platforms, the base function with no suffix and the one with the +C<_L1> suffix should be identical, since, as of this writing, the EBCDIC code +pages that Perl knows about all are equivalent to Latin-1. The function that +ends in an C<_A> suffix will not return true unless the specified character also +has an ASCII equivalent. =for apidoc Am|bool|isALPHA|char ch -Returns a boolean indicating whether the C C is an +Returns a boolean indicating whether the specified character is an alphabetic character in the platform's native character set. +See the L for an explanation of variants +C and C. -=for apidoc Am|bool|isSPACE|char ch -Returns a boolean indicating whether the C C is a -whitespace character in the platform's native character set. +=for apidoc Am|bool|isASCII|char ch +Returns a boolean indicating whether the specified character is one of the 128 +characters in the ASCII character set. On non-ASCII platforms, it is if this +character corresponds to an ASCII character. Variants C and +C are identical to C. =for apidoc Am|bool|isDIGIT|char ch -Returns a boolean indicating whether the C C is a +Returns a boolean indicating whether the specified character is a digit in the platform's native character set. +Variants C and C are identical to C. + +=for apidoc Am|bool|isLOWER|char ch +Returns a boolean indicating whether the specified character is a +lowercase character in the platform's native character set. +See the L for an explanation of variants +C and C. =for apidoc Am|bool|isOCTAL|char ch -Returns a boolean indicating whether the C C is an +Returns a boolean indicating whether the specified character is an octal digit, [0-7] in the platform's native character set. +Variants C and C are identical to C. + +=for apidoc Am|bool|isSPACE|char ch +Returns a boolean indicating whether the specified character is a +whitespace character in the platform's native character set. This is the same +as what C<\s> matches in a regular expression. +See the L for an explanation of variants +C and C. =for apidoc Am|bool|isUPPER|char ch -Returns a boolean indicating whether the C C is an +Returns a boolean indicating whether the specified character is an uppercase character in the platform's native character set. - -=for apidoc Am|bool|isLOWER|char ch -Returns a boolean indicating whether the C C is a -lowercase character in the platform's native character set. +See the L for an explanation of variants +C and C. + +=for apidoc Am|bool|isWORDCHAR|char ch +Returns a boolean indicating whether the specified character is a +character that is any of: alphabetic, numeric, or an underscore. This is the +same as what C<\w> matches in a regular expression. +C is a synonym provided for backward compatibility. Note that it +does not have the standard C language meaning of alphanumeric, since it matches +an underscore and the standard meaning does not. +See the L for an explanation of variants +C and C. + +=for apidoc Am|bool|isXDIGIT|char ch +Returns a boolean indicating whether the specified character is a hexadecimal +digit, [0-9A-Fa-f]. Variants C and C are +identical to C. =head1 Character case changing @@ -486,82 +558,249 @@ character set, if possible; otherwise returns the input character itself. =cut -NOTE: Since some of these are macros, there is no check in those that the -parameter is a char or U8. This means that if called with a larger width -parameter, casts can silently truncate and yield wrong results. - -Also note that these macros are repeated in Devel::PPPort, so should also be +Note that these macros are repeated in Devel::PPPort, so should also be patched there. The file as of this writing is cpan/Devel-PPPort/parts/inc/misc */ -/* FITS_IN_8_BITS(c) returns true if c occupies no more than 8 bits. It is - * designed to be hopefully bomb-proof, making sure that no bits of - * information are lost even on a 64-bit machine, but to get the compiler to - * optimize it out if possible. This is because Configure makes sure that the - * machine has an 8-bit byte, so if c is stored in a byte, the sizeof() - * guarantees that this evaluates to a constant true at compile time. The use - * of the mask instead of '< 256' keeps gcc from complaining that it is alway - * true, when c's storage class is a byte. Use U64TYPE because U64 is known - * only in the perl core, and this macro can be called from outside that */ +/* 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 FITS_IN_8_BITS(c) ((sizeof(c) == 1) || (((U64TYPE)(c) & 0xFF) == (U64TYPE)(c))) +# define WIDEST_UTYPE U64TYPE #else -# define FITS_IN_8_BITS(c) ((sizeof(c) == 1) || (((U32)(c) & 0xFF) == (U32)(c))) -#endif - -#define isALNUM(c) (isALPHA(c) || isDIGIT(c) || (c) == '_') -#define isIDFIRST(c) (isALPHA(c) || (c) == '_') -#define isALPHA(c) (isUPPER(c) || isLOWER(c)) -/* ALPHAU includes Unicode semantics for latin1 characters. It has an extra - * >= AA test to speed up ASCII-only tests at the expense of the others */ -/* XXX decide whether to document the ALPHAU, ALNUMU and isSPACE_L1 functions. - * Most of these should be implemented as table lookup for speed */ -#define isALPHAU(c) (isALPHA(c) || (NATIVE_TO_UNI((U8) c) >= 0xAA \ - && ((NATIVE_TO_UNI((U8) c) >= 0xC0 \ - && NATIVE_TO_UNI((U8) c) != 0xD7 && NATIVE_TO_UNI((U8) c) != 0xF7) \ - || NATIVE_TO_UNI((U8) c) == 0xAA \ - || NATIVE_TO_UNI((U8) c) == 0xB5 \ - || NATIVE_TO_UNI((U8) c) == 0xBA))) -#define isALNUMU(c) (isDIGIT(c) || isALPHAU(c) || (c) == '_') -#define isWORDCHAR_L1(c) isALNUMU(c) - -/* continuation character for legal NAME in \N{NAME} */ -#define isCHARNAME_CONT(c) (isALNUMU(c) || (c) == ' ' || (c) == '-' || (c) == '(' || (c) == ')' || (c) == ':' || NATIVE_TO_UNI((U8) c) == 0xA0) -#define isSPACE(c) \ - ((c) == ' ' || (c) == '\t' || (c) == '\n' || (c) =='\r' || (c) == '\f') -#define isSPACE_L1(c) (isSPACE(c) \ - || (NATIVE_TO_UNI(c) == 0x85 || NATIVE_TO_UNI(c) == 0xA0)) -#define isPSXSPC(c) (isSPACE(c) || (c) == '\v') -#define isBLANK(c) ((c) == ' ' || (c) == '\t') -#define isDIGIT(c) ((c) >= '0' && (c) <= '9') -#define isOCTAL(c) ((c) >= '0' && (c) <= '7') -#define isASCII(c) (FITS_IN_8_BITS(c) ? NATIVE_TO_UNI((U8) c) <= 127 : 0) +# define WIDEST_UTYPE U32 +#endif + +/* FITS_IN_8_BITS(c) returns true if c doesn't have a bit set other than in + * the lower 8. It is designed to be hopefully bomb-proof, making sure that no + * bits of information are lost even on a 64-bit machine, but to get the + * compiler to optimize it out if possible. This is because Configure makes + * sure that the machine has an 8-bit byte, so if c is stored in a byte, the + * sizeof() guarantees that this evaluates to a constant true at compile time. + */ +#define FITS_IN_8_BITS(c) ((sizeof(c) == 1) || !(((WIDEST_UTYPE)(c)) & ~0xFF)) + +#ifdef EBCDIC +# define isASCII(c) (FITS_IN_8_BITS(c) && (NATIVE_TO_UNI((U8) (c)) < 128)) +#else +# define isASCII(c) ((WIDEST_UTYPE)(c) < 128) +#endif + +#define isASCII_A(c) isASCII(c) +#define isASCII_L1(c) isASCII(c) + +/* The lower 3 bits in both the ASCII and EBCDIC representations of '0' are 0, + * and the 8 possible permutations of those bits exactly comprise the 8 octal + * digits */ +#define isOCTAL_A(c) cBOOL(FITS_IN_8_BITS(c) && (0xF8 & (c)) == '0') + +/* ASCII range only */ +#ifdef H_PERL /* If have access to perl.h, lookup in its table */ + +/* Character class numbers. These are used in PL_charclass[] and the ones + * up through the one that corresponds to <_HIGHEST_REGCOMP_DOT_H_SYNC> are + * used by regcomp.h. These use names used in l1_char_class_tab.h but their + * actual definitions are here. If that has a name not used here, it won't + * compile. */ +# define _CC_WORDCHAR 0 +# define _CC_SPACE 1 +# define _CC_DIGIT 2 +# define _CC_ALNUMC 3 +# define _CC_ALPHA 4 +# define _CC_ASCII 5 +# define _CC_CNTRL 6 +# define _CC_GRAPH 7 +# define _CC_LOWER 8 +# define _CC_PRINT 9 +# define _CC_PUNCT 10 +# define _CC_UPPER 11 +# define _CC_XDIGIT 12 +# define _CC_PSXSPC 13 +# define _CC_BLANK 14 +# define _HIGHEST_REGCOMP_DOT_H_SYNC _CC_BLANK + +# define _CC_IDFIRST 15 +# define _CC_CHARNAME_CONT 16 +# define _CC_NONLATIN1_FOLD 17 +# define _CC_QUOTEMETA 18 +# define _CC_NON_FINAL_FOLD 19 +/* Unused: 20-31 + * If more bits are needed, one could add a second word for non-64bit + * QUAD_IS_INT systems, using some #ifdefs to distinguish between having a 2nd + * word or not. */ + +# ifdef DOINIT +EXTCONST U32 PL_charclass[] = { +# include "l1_char_class_tab.h" +}; + +# else /* ! DOINIT */ +EXTCONST U32 PL_charclass[]; +# endif + + /* The 1U keeps Solaris from griping when shifting sets the uppermost bit */ +# define _CC_mask(classnum) (1U << (classnum)) +# define _generic_isCC(c, classnum) cBOOL(FITS_IN_8_BITS(c) \ + && (PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_mask(classnum))) + + /* The mask for the _A versions of the macros; it just adds in the bit for + * ASCII. */ +# define _CC_mask_A(classnum) (_CC_mask(classnum) | _CC_mask(_CC_ASCII)) + + /* The _A version makes sure that both the desired bit and the ASCII bit + * are present */ +# define _generic_isCC_A(c, classnum) (FITS_IN_8_BITS(c) \ + && ((PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_mask_A(classnum)) \ + == _CC_mask_A(classnum))) + +# define isALNUMC_A(c) _generic_isCC_A(c, _CC_ALNUMC) +# define isALPHA_A(c) _generic_isCC_A(c, _CC_ALPHA) +# define isBLANK_A(c) _generic_isCC_A(c, _CC_BLANK) +# define isCNTRL_A(c) _generic_isCC_A(c, _CC_CNTRL) +# define isDIGIT_A(c) _generic_isCC(c, _CC_DIGIT) +# define isGRAPH_A(c) _generic_isCC_A(c, _CC_GRAPH) +# define isLOWER_A(c) _generic_isCC_A(c, _CC_LOWER) +# define isPRINT_A(c) _generic_isCC_A(c, _CC_PRINT) +# define isPSXSPC_A(c) _generic_isCC_A(c, _CC_PSXSPC) +# define isPUNCT_A(c) _generic_isCC_A(c, _CC_PUNCT) +# define isSPACE_A(c) _generic_isCC_A(c, _CC_SPACE) +# define isUPPER_A(c) _generic_isCC_A(c, _CC_UPPER) +# define isWORDCHAR_A(c) _generic_isCC_A(c, _CC_WORDCHAR) +# define isXDIGIT_A(c) _generic_isCC(c, _CC_XDIGIT) +# define isIDFIRST_A(c) _generic_isCC_A(c, ( _CC_IDFIRST)) + + /* Either participates in a fold with a character above 255, or is a + * multi-char fold */ +# define _HAS_NONLATIN1_FOLD_CLOSURE_ONLY_FOR_USE_BY_REGCOMP_DOT_C_AND_REGEXEC_DOT_C(c) ((! cBOOL(FITS_IN_8_BITS(c))) || (PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_mask(_CC_NONLATIN1_FOLD))) + +# define _isQUOTEMETA(c) _generic_isCC(c, _CC_QUOTEMETA) +# define _IS_NON_FINAL_FOLD_ONLY_FOR_USE_BY_REGCOMP_DOT_C(c) \ + _generic_isCC(c, _CC_NON_FINAL_FOLD) +#else /* No perl.h. */ +# ifdef EBCDIC +# define isALNUMC_A(c) (isASCII(c) && isALNUMC(c)) +# define isALPHA_A(c) (isASCII(c) && isALPHA(c)) +# define isBLANK_A(c) (isASCII(c) && isBLANK(c)) +# define isCNTRL_A(c) (isASCII(c) && isCNTRL(c)) +# define isDIGIT_A(c) (isASCII(c) && isDIGIT(c)) +# define isGRAPH_A(c) (isASCII(c) && isGRAPH(c)) +# define isIDFIRST_A(c) (isASCII(c) && isIDFIRST(c)) +# define isLOWER_A(c) (isASCII(c) && isLOWER(c)) +# define isPRINT_A(c) (isASCII(c) && isPRINT(c)) +# define isPSXSPC_A(c) (isASCII(c) && isPSXSPC(c)) +# define isPUNCT_A(c) (isASCII(c) && isPUNCT(c)) +# define isSPACE_A(c) (isASCII(c) && isSPACE(c)) +# define isUPPER_A(c) (isASCII(c) && isUPPER(c)) +# define isWORDCHAR_A(c) (isASCII(c) && isWORDCHAR(c)) +# define isXDIGIT_A(c) (isASCII(c) && isXDIGIT(c)) +# else /* ASCII platform, no perl.h */ +# define isALNUMC_A(c) (isALPHA_A(c) || isDIGIT_A(c)) +# define isALPHA_A(c) (isUPPER_A(c) || isLOWER_A(c)) +# define isBLANK_A(c) ((c) == ' ' || (c) == '\t') +# define isCNTRL_A(c) (FITS_IN_8_BITS(c) && ((U8) (c) < ' ' || (c) == 127)) +# define isDIGIT_A(c) ((c) <= '9' && (c) >= '0') +# define isGRAPH_A(c) (isWORDCHAR_A(c) || isPUNCT_A(c)) +# define isIDFIRST_A(c) (isALPHA_A(c) || (c) == '_') +# define isLOWER_A(c) ((c) >= 'a' && (c) <= 'z') +# define isPRINT_A(c) (((c) >= 32 && (c) < 127)) +# define isPSXSPC_A(c) (isSPACE_A(c) || (c) == '\v') +# define isPUNCT_A(c) (((c) >= 33 && (c) <= 47) || ((c) >= 58 && (c) <= 64) || ((c) >= 91 && (c) <= 96) || ((c) >= 123 && (c) <= 126)) +# define isSPACE_A(c) ((c) == ' ' || (c) == '\t' || (c) == '\n' || (c) =='\r' || (c) == '\f') +# define isUPPER_A(c) ((c) <= 'Z' && (c) >= 'A') +# define isWORDCHAR_A(c) (isALPHA_A(c) || isDIGIT_A(c) || (c) == '_') +# define isXDIGIT_A(c) (isDIGIT_A(c) || ((c) >= 'a' && (c) <= 'f') || ((c) <= 'F' && (c) >= 'A')) +# endif +#endif /* ASCII range definitions */ + +/* Latin1 definitions */ +#ifdef H_PERL +# define isALNUMC_L1(c) _generic_isCC(c, _CC_ALNUMC) +# define isALPHA_L1(c) _generic_isCC(c, _CC_ALPHA) +# define isBLANK_L1(c) _generic_isCC(c, _CC_BLANK) +/* continuation character for legal NAME in \N{NAME} */ +# define isCHARNAME_CONT(c) _generic_isCC(c, _CC_CHARNAME_CONT) +# define isCNTRL_L1(c) _generic_isCC(c, _CC_CNTRL) +# define isGRAPH_L1(c) _generic_isCC(c, _CC_GRAPH) +# define isLOWER_L1(c) _generic_isCC(c, _CC_LOWER) +# define isPRINT_L1(c) _generic_isCC(c, _CC_PRINT) +# define isPSXSPC_L1(c) _generic_isCC(c, _CC_PSXSPC) +# define isPUNCT_L1(c) _generic_isCC(c, _CC_PUNCT) +# define isSPACE_L1(c) _generic_isCC(c, _CC_SPACE) +# define isUPPER_L1(c) _generic_isCC(c, _CC_UPPER) +# define isWORDCHAR_L1(c) _generic_isCC(c, _CC_WORDCHAR) +# define isIDFIRST_L1(c) _generic_isCC(c, _CC_IDFIRST) +#else /* No access to perl.h. Only a few provided here, just in case needed + * for backwards compatibility */ + /* ALPHAU includes Unicode semantics for latin1 characters. It has an extra + * >= AA test to speed up ASCII-only tests at the expense of the others */ +# define isALPHA_L1(c) (isALPHA(c) || (NATIVE_TO_UNI((U8) c) >= 0xAA \ + && ((NATIVE_TO_UNI((U8) c) >= 0xC0 \ + && NATIVE_TO_UNI((U8) c) != 0xD7 && NATIVE_TO_UNI((U8) c) != 0xF7) \ + || NATIVE_TO_UNI((U8) c) == 0xAA \ + || NATIVE_TO_UNI((U8) c) == 0xB5 \ + || NATIVE_TO_UNI((U8) c) == 0xBA))) +# define isCHARNAME_CONT(c) (isALNUM_L1(c) || (c) == ' ' || (c) == '-' || (c) == '(' || (c) == ')' || (c) == ':' || NATIVE_TO_UNI((U8) c) == 0xA0) +#endif + +/* Macros for backwards compatibility and for completeness when the ASCII and + * Latin1 values are identical */ +#define isALNUM(c) isWORDCHAR(c) +#define isALNUMU(c) isWORDCHAR_L1(c) +#define isALPHAU(c) isALPHA_L1(c) +#define isDIGIT_L1(c) isDIGIT_A(c) +#define isOCTAL(c) isOCTAL_A(c) +#define isOCTAL_L1(c) isOCTAL_A(c) +#define isXDIGIT_L1(c) isXDIGIT_A(c) + +/* Macros that differ between EBCDIC and ASCII. Where C89 defines a function, + * that is used in the EBCDIC form, because in EBCDIC we do not do locales: + * therefore can use native functions. For those where C89 doesn't define a + * function, use our function, assuming that the EBCDIC code page is isomorphic + * with Latin1, which the three currently recognized by Perl are. Some libc's + * have an isblank(), but it's not guaranteed. */ #ifdef EBCDIC - /* In EBCDIC we do not do locales: therefore() isupper() is fine. */ -# define isUPPER(c) isupper(c) -# define isLOWER(c) islower(c) # define isALNUMC(c) isalnum(c) +# define isALPHA(c) isalpha(c) +# define isBLANK(c) ((c) == ' ' || (c) == '\t' || NATIVE_TO_UNI(c) == 0xA0) # define isCNTRL(c) iscntrl(c) +# define isDIGIT(c) isdigit(c) # define isGRAPH(c) isgraph(c) +# define isIDFIRST(c) (isALPHA(c) || (c) == '_') +# define isLOWER(c) islower(c) # define isPRINT(c) isprint(c) +# define isPSXSPC(c) isspace(c) # define isPUNCT(c) ispunct(c) +# define isSPACE(c) (isPSXSPC(c) && (c) != '\v') +# define isUPPER(c) isupper(c) # define isXDIGIT(c) isxdigit(c) -# define toUPPER(c) toupper(c) +# define isWORDCHAR(c) (isalnum(c) || (c) == '_') # define toLOWER(c) tolower(c) -#else -# define isUPPER(c) ((c) >= 'A' && (c) <= 'Z') -# define isLOWER(c) ((c) >= 'a' && (c) <= 'z') -# define isALNUMC(c) (isALPHA(c) || isDIGIT(c)) -# define isCNTRL(c) ((U8) (c) < ' ' || (c) == 127) -# define isGRAPH(c) (isALNUM(c) || isPUNCT(c)) -# define isPRINT(c) (((c) >= 32 && (c) < 127)) -# define isPUNCT(c) (((c) >= 33 && (c) <= 47) || ((c) >= 58 && (c) <= 64) || ((c) >= 91 && (c) <= 96) || ((c) >= 123 && (c) <= 126)) -# define isXDIGIT(c) (isDIGIT(c) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F')) - -/* ASCII casing. */ -# define toUPPER(c) (isLOWER(c) ? (c) - ('a' - 'A') : (c)) +# define toUPPER(c) toupper(c) +#else /* Not EBCDIC: ASCII-only matching */ +# define isALNUMC(c) isALNUMC_A(c) /* Mnemonic: "C's alnum" = alpha + digit */ +# define isALPHA(c) isALPHA_A(c) +# define isBLANK(c) isBLANK_A(c) +# define isCNTRL(c) isCNTRL_A(c) +# define isDIGIT(c) isDIGIT_A(c) +# define isGRAPH(c) isGRAPH_A(c) +# define isIDFIRST(c) isIDFIRST_A(c) +# define isLOWER(c) isLOWER_A(c) +# define isPRINT(c) isPRINT_A(c) +# define isPSXSPC(c) isPSXSPC_A(c) +# define isPUNCT(c) isPUNCT_A(c) +# define isSPACE(c) isSPACE_A(c) +# define isUPPER(c) isUPPER_A(c) +# define isWORDCHAR(c) isWORDCHAR_A(c) +# define isXDIGIT(c) isXDIGIT_A(c) + + /* ASCII casing. These could also be written as + #define toLOWER(c) (isASCII(c) ? toLOWER_LATIN1(c) : (c)) + #define toUPPER(c) (isASCII(c) ? toUPPER_LATIN1_MOD(c) : (c)) + which uses table lookup and mask instead of subtraction. (This would + work because the _MOD does not apply in the ASCII range) */ # define toLOWER(c) (isUPPER(c) ? (c) + ('a' - 'A') : (c)) +# define toUPPER(c) (isLOWER(c) ? (c) - ('a' - 'A') : (c)) #endif @@ -586,6 +825,8 @@ patched there. The file as of this writing is cpan/Devel-PPPort/parts/inc/misc # define isIDFIRST_LC(c) \ (NXIsAlpha((unsigned int)(c)) || (char)(c) == '_') # define isALPHA_LC(c) NXIsAlpha((unsigned int)(c)) +# define isASCII_LC(c) isASCII((unsigned int)(c)) +# define isBLANK_LC(c) isBLANK((unsigned int)(c)) # define isSPACE_LC(c) NXIsSpace((unsigned int)(c)) # define isDIGIT_LC(c) NXIsDigit((unsigned int)(c)) # define isUPPER_LC(c) NXIsUpper((unsigned int)(c)) @@ -602,9 +843,23 @@ patched there. The file as of this writing is cpan/Devel-PPPort/parts/inc/misc # if defined(CTYPE256) || (!defined(isascii) && !defined(HAS_ISASCII)) +/* Note that the foo_LC() macros in this case generally are defined only on + * code points 0-256, and give undefined, unwarned results if called with + * values outside that range */ + # define isALNUM_LC(c) (isalnum((unsigned char)(c)) || (char)(c) == '_') # define isIDFIRST_LC(c) (isalpha((unsigned char)(c)) || (char)(c) == '_') # define isALPHA_LC(c) isalpha((unsigned char)(c)) +# ifdef HAS_ISASCII +# define isASCII_LC(c) isascii((unsigned char)(c)) +# else +# define isASCII_LC(c) isASCII((unsigned char)(c)) +# endif +# ifdef HAS_ISBLANK +# define isBLANK_LC(c) isblank((unsigned char)(c)) +# else +# define isBLANK_LC(c) isBLANK((unsigned char)(c)) +# endif # define isSPACE_LC(c) isspace((unsigned char)(c)) # define isDIGIT_LC(c) isdigit((unsigned char)(c)) # define isUPPER_LC(c) isupper((unsigned char)(c)) @@ -622,6 +877,12 @@ patched there. The file as of this writing is cpan/Devel-PPPort/parts/inc/misc # define isALNUM_LC(c) (isascii(c) && (isalnum(c) || (c) == '_')) # define isIDFIRST_LC(c) (isascii(c) && (isalpha(c) || (c) == '_')) # define isALPHA_LC(c) (isascii(c) && isalpha(c)) +# define isASCII_LC(c) isascii(c) +# ifdef HAS_ISBLANK +# define isBLANK_LC(c) (isascii(c) && isblank(c)) +# else +# define isBLANK_LC(c) isBLANK(c) +# endif # define isSPACE_LC(c) (isascii(c) && isspace(c)) # define isDIGIT_LC(c) (isascii(c) && isdigit(c)) # define isUPPER_LC(c) (isascii(c) && isupper(c)) @@ -638,29 +899,42 @@ patched there. The file as of this writing is cpan/Devel-PPPort/parts/inc/misc #endif /* USE_NEXT_CTYPE */ #define isPSXSPC_LC(c) (isSPACE_LC(c) || (c) == '\v') -#define isBLANK_LC(c) isBLANK(c) /* could be wrong */ - -#define isALNUM_uni(c) is_uni_alnum(c) -#define isIDFIRST_uni(c) is_uni_idfirst(c) -#define isALPHA_uni(c) is_uni_alpha(c) -#define isSPACE_uni(c) is_uni_space(c) -#define isDIGIT_uni(c) is_uni_digit(c) -#define isUPPER_uni(c) is_uni_upper(c) -#define isLOWER_uni(c) is_uni_lower(c) -#define isASCII_uni(c) is_uni_ascii(c) -#define isCNTRL_uni(c) is_uni_cntrl(c) -#define isGRAPH_uni(c) is_uni_graph(c) -#define isPRINT_uni(c) is_uni_print(c) -#define isPUNCT_uni(c) is_uni_punct(c) -#define isXDIGIT_uni(c) is_uni_xdigit(c) + +/* For use in the macros just below. If the input is Latin1, use the Latin1 + * (_L1) version of the macro; otherwise use the function. Won't compile if + * 'c' isn't unsigned, as won't match function prototype. The macros do bounds + * checking, so have duplicate checks here, so could create versions of the + * macros that don't, but experiments show that gcc optimizes them out anyway. + */ +#define generic_uni(macro, function, c) ((c) < 256 \ + ? CAT2(macro, _L1)(c) \ + : function(c)) +/* Note that all ignore 'use bytes' */ + +#define isALNUM_uni(c) generic_uni(isWORDCHAR, is_uni_alnum, c) +#define isBLANK_uni(c) generic_uni(isBLANK, is_uni_blank, c) +#define isIDFIRST_uni(c) generic_uni(isIDFIRST, is_uni_idfirst, c) +#define isALPHA_uni(c) generic_uni(isALPHA, is_uni_alpha, c) +#define isSPACE_uni(c) generic_uni(isSPACE, is_uni_space, c) +#define isDIGIT_uni(c) generic_uni(isDIGIT, is_uni_digit, c) +#define isUPPER_uni(c) generic_uni(isUPPER, is_uni_upper, c) +#define isLOWER_uni(c) generic_uni(isLOWER, is_uni_lower, c) +#define isASCII_uni(c) isASCII(c) +/* All controls are in Latin1 */ +#define isCNTRL_uni(c) isCNTRL_L1(c) +#define isGRAPH_uni(c) generic_uni(isGRAPH, is_uni_graph, c) +#define isPRINT_uni(c) generic_uni(isPRINT, is_uni_print, c) +#define isPUNCT_uni(c) generic_uni(isPUNCT, is_uni_punct, c) +#define isXDIGIT_uni(c) generic_uni(isXDIGIT, is_uni_xdigit, c) + +/* Posix and regular space differ only in U+000B, which is in Latin1 */ +#define isPSXSPC_uni(c) ((c) < 256 ? isPSXSPC_L1(c) : isSPACE_uni(c)) + #define toUPPER_uni(c,s,l) to_uni_upper(c,s,l) #define toTITLE_uni(c,s,l) to_uni_title(c,s,l) #define toLOWER_uni(c,s,l) to_uni_lower(c,s,l) #define toFOLD_uni(c,s,l) to_uni_fold(c,s,l) -#define isPSXSPC_uni(c) (isSPACE_uni(c) ||(c) == '\f') -#define isBLANK_uni(c) isBLANK(c) /* could be wrong */ - #define isALNUM_LC_uvchr(c) (c < 256 ? isALNUM_LC(c) : is_uni_alnum_lc(c)) #define isIDFIRST_LC_uvchr(c) (c < 256 ? isIDFIRST_LC(c) : is_uni_idfirst_lc(c)) #define isALPHA_LC_uvchr(c) (c < 256 ? isALPHA_LC(c) : is_uni_alpha_lc(c)) @@ -676,44 +950,77 @@ patched there. The file as of this writing is cpan/Devel-PPPort/parts/inc/misc #define isPSXSPC_LC_uni(c) (isSPACE_LC_uni(c) ||(c) == '\f') #define isBLANK_LC_uni(c) isBLANK(c) /* could be wrong */ -#define isALNUM_utf8(p) is_utf8_alnum(p) -/* The ID_Start of Unicode is quite limiting: it assumes a L-class - * character (meaning that you cannot have, say, a CJK character). - * Instead, let's allow ID_Continue but not digits. */ -#define isIDFIRST_utf8(p) (is_utf8_idcont(p) && !is_utf8_digit(p)) -#define isALPHA_utf8(p) is_utf8_alpha(p) -#define isSPACE_utf8(p) is_utf8_space(p) -#define isDIGIT_utf8(p) is_utf8_digit(p) -#define isUPPER_utf8(p) is_utf8_upper(p) -#define isLOWER_utf8(p) is_utf8_lower(p) -#define isASCII_utf8(p) is_utf8_ascii(p) -#define isCNTRL_utf8(p) is_utf8_cntrl(p) -#define isGRAPH_utf8(p) is_utf8_graph(p) -#define isPRINT_utf8(p) is_utf8_print(p) -#define isPUNCT_utf8(p) is_utf8_punct(p) -#define isXDIGIT_utf8(p) is_utf8_xdigit(p) +/* For use in the macros just below. If the input is ASCII, use the ASCII (_A) + * version of the macro; if the input is in the upper Latin1 range, use the + * Latin1 (_L1) version of the macro, after converting from utf8; otherwise use + * the function. This relies on the fact that ASCII characters have the same + * representation whether utf8 or not */ +#define generic_utf8(macro, function, p) (isASCII(*(p)) \ + ? CAT2(CAT2(macro,_),A)(*(p)) \ + : (UTF8_IS_DOWNGRADEABLE_START(*(p))) \ + ? CAT2(macro, _L1) \ + (TWO_BYTE_UTF8_TO_UNI(*(p), \ + *((p)+1))) \ + : function(p)) + +/* Note that all assume that the utf8 has been validated, and ignore 'use + * bytes' */ + +#define isALNUM_utf8(p) generic_utf8(isWORDCHAR, is_utf8_alnum, p) +/* To prevent S_scan_word in toke.c from hanging, we have to make sure that + * IDFIRST is an alnum. See + * http://rt.perl.org/rt3/Ticket/Display.html?id=74022 for more detail than you + * ever wanted to know about. XXX It is unclear if this should extend to + * isIDFIRST_uni() which it hasn't so far. (In the ASCII range, there isn't a + * difference.) This used to be not the XID version, but we decided to go with + * the more modern Unicode definition */ +#define isIDFIRST_utf8(p) (isASCII(*(p)) \ + ? isIDFIRST_A(*(p)) \ + : (UTF8_IS_DOWNGRADEABLE_START(*(p))) \ + ? isIDFIRST_L1(TWO_BYTE_UTF8_TO_UNI(*(p), \ + *((p)+1)))\ + : Perl__is_utf8__perl_idstart(aTHX_ p)) +#define isIDCONT_utf8(p) generic_utf8(isWORDCHAR, is_utf8_xidcont, p) +#define isALPHA_utf8(p) generic_utf8(isALPHA, is_utf8_alpha, p) +#define isBLANK_utf8(p) generic_utf8(isBLANK, is_utf8_blank, p) +#define isSPACE_utf8(p) generic_utf8(isSPACE, is_utf8_space, p) +#define isDIGIT_utf8(p) generic_utf8(isDIGIT, is_utf8_digit, p) +#define isUPPER_utf8(p) generic_utf8(isUPPER, is_utf8_upper, p) +#define isLOWER_utf8(p) generic_utf8(isLOWER, is_utf8_lower, p) +/* Because ASCII is invariant under utf8, the non-utf8 macro works */ +#define isASCII_utf8(p) isASCII(*p) +#define isCNTRL_utf8(p) generic_utf8(isCNTRL, is_utf8_cntrl, p) +#define isGRAPH_utf8(p) generic_utf8(isGRAPH, is_utf8_graph, p) +#define isPRINT_utf8(p) generic_utf8(isPRINT, is_utf8_print, p) +#define isPUNCT_utf8(p) generic_utf8(isPUNCT, is_utf8_punct, p) +#define isXDIGIT_utf8(p) generic_utf8(isXDIGIT, is_utf8_xdigit, p) #define toUPPER_utf8(p,s,l) to_utf8_upper(p,s,l) #define toTITLE_utf8(p,s,l) to_utf8_title(p,s,l) #define toLOWER_utf8(p,s,l) to_utf8_lower(p,s,l) -#define isPSXSPC_utf8(c) (isSPACE_utf8(c) ||(c) == '\f') -#define isBLANK_utf8(c) isBLANK(c) /* could be wrong */ - -#define isALNUM_LC_utf8(p) isALNUM_LC_uvchr(utf8_to_uvchr(p, 0)) -#define isIDFIRST_LC_utf8(p) isIDFIRST_LC_uvchr(utf8_to_uvchr(p, 0)) -#define isALPHA_LC_utf8(p) isALPHA_LC_uvchr(utf8_to_uvchr(p, 0)) -#define isSPACE_LC_utf8(p) isSPACE_LC_uvchr(utf8_to_uvchr(p, 0)) -#define isDIGIT_LC_utf8(p) isDIGIT_LC_uvchr(utf8_to_uvchr(p, 0)) -#define isUPPER_LC_utf8(p) isUPPER_LC_uvchr(utf8_to_uvchr(p, 0)) -#define isLOWER_LC_utf8(p) isLOWER_LC_uvchr(utf8_to_uvchr(p, 0)) -#define isALNUMC_LC_utf8(p) isALNUMC_LC_uvchr(utf8_to_uvchr(p, 0)) -#define isCNTRL_LC_utf8(p) isCNTRL_LC_uvchr(utf8_to_uvchr(p, 0)) -#define isGRAPH_LC_utf8(p) isGRAPH_LC_uvchr(utf8_to_uvchr(p, 0)) -#define isPRINT_LC_utf8(p) isPRINT_LC_uvchr(utf8_to_uvchr(p, 0)) -#define isPUNCT_LC_utf8(p) isPUNCT_LC_uvchr(utf8_to_uvchr(p, 0)) +/* Posix and regular space differ only in U+000B, which is in ASCII (and hence + * Latin1 */ +#define isPSXSPC_utf8(p) ((isASCII(*(p))) \ + ? isPSXSPC_A(*(p)) \ + : (UTF8_IS_DOWNGRADEABLE_START(*(p)) \ + ? isPSXSPC_L1(TWO_BYTE_UTF8_TO_UNI(*(p), \ + *((p)+1)))\ + : isSPACE_utf8(p))) +#define isALNUM_LC_utf8(p) isALNUM_LC_uvchr(valid_utf8_to_uvchr(p, 0)) +#define isIDFIRST_LC_utf8(p) isIDFIRST_LC_uvchr(valid_utf8_to_uvchr(p, 0)) +#define isALPHA_LC_utf8(p) isALPHA_LC_uvchr(valid_utf8_to_uvchr(p, 0)) +#define isBLANK_LC_utf8(p) isBLANK_LC_uvchr(valid_utf8_to_uvchr(p, 0)) +#define isSPACE_LC_utf8(p) isSPACE_LC_uvchr(valid_utf8_to_uvchr(p, 0)) +#define isDIGIT_LC_utf8(p) isDIGIT_LC_uvchr(valid_utf8_to_uvchr(p, 0)) +#define isUPPER_LC_utf8(p) isUPPER_LC_uvchr(valid_utf8_to_uvchr(p, 0)) +#define isLOWER_LC_utf8(p) isLOWER_LC_uvchr(valid_utf8_to_uvchr(p, 0)) +#define isALNUMC_LC_utf8(p) isALNUMC_LC_uvchr(valid_utf8_to_uvchr(p, 0)) +#define isCNTRL_LC_utf8(p) isCNTRL_LC_uvchr(valid_utf8_to_uvchr(p, 0)) +#define isGRAPH_LC_utf8(p) isGRAPH_LC_uvchr(valid_utf8_to_uvchr(p, 0)) +#define isPRINT_LC_utf8(p) isPRINT_LC_uvchr(valid_utf8_to_uvchr(p, 0)) +#define isPUNCT_LC_utf8(p) isPUNCT_LC_uvchr(valid_utf8_to_uvchr(p, 0)) #define isPSXSPC_LC_utf8(c) (isSPACE_LC_utf8(c) ||(c) == '\f') -#define isBLANK_LC_utf8(c) isBLANK(c) /* could be wrong */ /* This conversion works both ways, strangely enough. On EBCDIC platforms, * CTRL-@ is 0, CTRL-A is 1, etc, just like on ASCII */ @@ -745,7 +1052,7 @@ The XSUB-writer's interface to the C C function. In 5.9.3, Newx() and friends replace the older New() API, and drops the first parameter, I, a debug aid which allowed callers to identify themselves. This aid has been superseded by a new build option, -PERL_MEM_LOG (see L). The older API is still +PERL_MEM_LOG (see L). The older API is still there for use in XS modules supporting older perls. =for apidoc Am|void|Newxc|void* ptr|int nitems|type|cast @@ -795,7 +1102,7 @@ destination, C is the number of items, and C is the type. Like C but returns dest. Useful for encouraging compilers to tail-call optimise. -=for apidoc Am|void|StructCopy|type src|type dest|type +=for apidoc Am|void|StructCopy|type *src|type *dest|type This is an architecture-independent macro to copy one structure to another. =for apidoc Am|void|PoisonWith|void* dest|int nitems|type|U8 byte @@ -1009,8 +1316,8 @@ void Perl_mem_log_del_sv(const SV *sv, const char *filename, const int linenumbe * Local variables: * c-indentation-style: bsd * c-basic-offset: 4 - * indent-tabs-mode: t + * indent-tabs-mode: nil * End: * - * ex: set ts=8 sts=4 sw=4 noet: + * ex: set ts=8 sts=4 sw=4 et: */