typedef U16TYPE U16;
typedef I32TYPE I32;
typedef U32TYPE U32;
-#ifdef PERL_CORE
-# ifdef HAS_QUAD
+
+#ifdef HAS_QUAD
typedef I64TYPE I64;
typedef U64TYPE U64;
-# endif
-#endif /* PERL_CORE */
+#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
# define PeRl_UINT64_C(c) CAT2(c,UI64)
# endif
# ifndef PeRl_INT64_C
-# define PeRl_INT64_C(c) ((I64TYPE)(c)) /* last resort */
-# define PeRl_UINT64_C(c) ((U64TYPE)(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
#define TYPE_DIGITS(T) BIT_DIGITS(sizeof(T) * 8)
#define TYPE_CHARS(T) (TYPE_DIGITS(T) + 2) /* sign, NUL */
+/* Unused by core; should be deprecated */
#define Ctl(ch) ((ch) & 037)
/* This is a helper macro to avoid preprocessor issues, replaced by nothing
* unless under DEBUGGING, where it expands to an assert of its argument,
* followed by a comma (hence the comma operator). If we just used a straight
- * assert(), we would get a comma with nothing before it when not DEBUGGING */
-#ifdef DEBUGGING
+ * assert(), we would get a comma with nothing before it when not DEBUGGING.
+ *
+ * We also use empty definition under Coverity since the __ASSERT__
+ * checks often check for things that Really Cannot Happen, and Coverity
+ * detects that and gets all excited. */
+
+#if defined(DEBUGGING) && !defined(__COVERITY__)
# define __ASSERT_(statement) assert(statement),
#else
# define __ASSERT_(statement)
=head1 Miscellaneous Functions
=for apidoc Am|bool|strNE|char* s1|char* s2
-Test two strings to see if they are different. Returns true or
-false.
+Test two C<NUL>-terminated strings to see if they are different. Returns true
+or false.
=for apidoc Am|bool|strEQ|char* s1|char* s2
-Test two strings to see if they are equal. Returns true or false.
+Test two C<NUL>-terminated strings to see if they are equal. Returns true or
+false.
=for apidoc Am|bool|strLT|char* s1|char* s2
-Test two strings to see if the first, C<s1>, is less than the second,
-C<s2>. Returns true or false.
+Test two C<NUL>-terminated strings to see if the first, C<s1>, is less than the
+second, C<s2>. Returns true or false.
=for apidoc Am|bool|strLE|char* s1|char* s2
-Test two strings to see if the first, C<s1>, is less than or equal to the
-second, C<s2>. Returns true or false.
+Test two C<NUL>-terminated strings to see if the first, C<s1>, is less than or
+equal to the second, C<s2>. Returns true or false.
=for apidoc Am|bool|strGT|char* s1|char* s2
-Test two strings to see if the first, C<s1>, is greater than the second,
-C<s2>. Returns true or false.
+Test two C<NUL>-terminated strings to see if the first, C<s1>, is greater than
+the second, C<s2>. Returns true or false.
=for apidoc Am|bool|strGE|char* s1|char* s2
-Test two strings to see if the first, C<s1>, is greater than or equal to
-the second, C<s2>. Returns true or false.
+Test two C<NUL>-terminated strings to see if the first, C<s1>, is greater than
+or equal to the second, C<s2>. Returns true or false.
=for apidoc Am|bool|strnNE|char* s1|char* s2|STRLEN len
-Test two strings to see if they are different. The C<len> parameter
-indicates the number of bytes to compare. Returns true or false. (A
+Test two C<NUL>-terminated strings to see if they are different. The C<len>
+parameter indicates the number of bytes to compare. Returns true or false. (A
wrapper for C<strncmp>).
=for apidoc Am|bool|strnEQ|char* s1|char* s2|STRLEN len
-Test two strings to see if they are equal. The C<len> parameter indicates
-the number of bytes to compare. Returns true or false. (A wrapper for
-C<strncmp>).
+Test two C<NUL>-terminated strings to see if they are equal. The C<len>
+parameter indicates the number of bytes to compare. Returns true or false. (A
+wrapper for C<strncmp>).
+
+=for apidoc Am|bool|memEQ|char* s1|char* s2|STRLEN len
+Test two buffers (which may contain embedded C<NUL> characters, to see if they
+are equal. The C<len> parameter indicates the number of bytes to compare.
+Returns zero if equal, or non-zero if non-equal.
+
+=for apidoc Am|bool|memNE|char* s1|char* s2|STRLEN len
+Test two buffers (which may contain embedded C<NUL> characters, to see if they
+are not equal. The C<len> parameter indicates the number of bytes to compare.
+Returns zero if non-equal, or non-zero if equal.
=cut
*/
WITH MACRON in Unicode, and is a word character.
Variant C<isFOO_utf8> is like C<isFOO_uni>, but the input is a pointer to a
-(known to be well-formed) UTF-8 encoded string (C<U8*> or C<char*>). The
-classification of just the first (possibly multi-byte) character in the string
-is tested.
+(known to be well-formed) UTF-8 encoded string (C<U8*> or C<char*>, and
+possibly containing embedded C<NUL> characters). The classification of just
+the first (possibly multi-byte) character in the string is tested.
Variant C<isFOO_LC> is like the C<isFOO_A> and C<isFOO_L1> variants, but the
result is based on the current locale, which is what C<LC> in the name stands
the published Unicode rules; otherwise, it uses the C library function that
gives the named classification. For example, C<isDIGIT_LC()> when not in a
UTF-8 locale returns the result of calling C<isdigit()>. FALSE is always
-returned if the input won't fit into an octet.
+returned if the input won't fit into an octet. On some platforms where the C
+library function is known to be defective, Perl changes its result to follow
+the POSIX standard's rules.
Variant C<isFOO_LC_uvchr> is like C<isFOO_LC>, but is defined on any UV. It
returns the same as C<isFOO_LC> for input code points less than 256, and
returns the hard-coded, not-affected-by-locale, Unicode results for larger ones.
-Variant C<isFOO_LC_utf8> is like C<isFOO_LC_uvchr>, but the input is a pointer to a
-(known to be well-formed) UTF-8 encoded string (C<U8*> or C<char*>). The
-classification of just the first (possibly multi-byte) character in the string
-is tested.
+Variant C<isFOO_LC_utf8> is like C<isFOO_LC_uvchr>, but the input is a pointer
+to a (known to be well-formed) UTF-8 encoded string (C<U8*> or C<char*>, and
+possibly containing embedded C<NUL> characters). The classification of just
+the first (possibly multi-byte) character in the string is tested.
=for apidoc Am|bool|isALPHA|char ch
Returns a boolean indicating whether the specified character is an
Returns a boolean indicating whether the specified character is a
whitespace character. This is analogous
to what C<m/\s/> matches in a regular expression. Starting in Perl 5.18
-(experimentally), this also matches what C<m/[[:space:]]/> does.
-("Experimentally" means that this change may be backed out in 5.22 if
-field experience indicates that it was unwise.) Prior to 5.18, only the
+this also matches what C<m/[[:space:]]/> does. Prior to 5.18, only the
locale forms of this macro (the ones with C<LC> in their names) matched
precisely what C<m/[[:space:]]/> does. In those releases, the only difference,
in the non-locale variants, was that C<isSPACE()> did not match a vertical tab.
=for apidoc Am|bool|isPSXSPC|char ch
(short for Posix Space)
-Starting in 5.18, this is identical (experimentally) in all its forms to the
-corresponding C<isSPACE()> macros. ("Experimentally" means that this change
-may be backed out in 5.22 if field experience indicates that it
-was unwise.)
+Starting in 5.18, this is identical in all its forms to the
+corresponding C<isSPACE()> macros.
The locale forms of this macro are identical to their corresponding
C<isSPACE()> forms in all Perl releases. In releases prior to 5.18, the
non-locale forms differ from their C<isSPACE()> forms only in that the
Otherwise they are identical. Thus this macro is analogous to what
C<m/[[:space:]]/> matches in a regular expression.
See the L<top of this section|/Character classification> for an explanation of
-variants
-C<isPSXSPC_A>, C<isPSXSPC_L1>, C<isPSXSPC_uni>, C<isPSXSPC_utf8>, C<isPSXSPC_LC>,
-C<isPSXSPC_LC_uvchr>, and C<isPSXSPC_LC_utf8>.
+variants C<isPSXSPC_A>, C<isPSXSPC_L1>, C<isPSXSPC_uni>, C<isPSXSPC_utf8>,
+C<isPSXSPC_LC>, C<isPSXSPC_LC_uvchr>, and C<isPSXSPC_LC_utf8>.
=for apidoc Am|bool|isUPPER|char ch
Returns a boolean indicating whether the specified character is an
alphanumeric.
See the L<top of this section|/Character classification> for an explanation of
variants
-C<isWORDCHAR_A>, C<isWORDCHAR_L1>, C<isWORDCHAR_uni>, C<isWORDCHAR_utf8>,
-C<isWORDCHAR_LC>, C<isWORDCHAR_LC_uvchr>, and C<isWORDCHAR_LC_utf8>.
+C<isWORDCHAR_A>, C<isWORDCHAR_L1>, C<isWORDCHAR_uni>, and C<isWORDCHAR_utf8>.
+C<isWORDCHAR_LC>, C<isWORDCHAR_LC_uvchr>, and C<isWORDCHAR_LC_utf8> are also as
+described there, but additionally include the platform's native underscore.
=for apidoc Am|bool|isXDIGIT|char ch
Returns a boolean indicating whether the specified character is a hexadecimal
C<toLOWER_A> is equivalent.
=for apidoc Am|U8|toLOWER_L1|U8 ch
-Converts the specified Latin1 character to lowercase. The results are undefined if
-the input doesn't fit in a byte.
+Converts the specified Latin1 character to lowercase. The results are
+undefined if the input doesn't fit in a byte.
=for apidoc Am|U8|toLOWER_LC|U8 ch
Converts the specified character to lowercase using the current locale's rules,
The input character at C<p> is assumed to be well-formed.
-=for apidoc Am|U8|toLOWER_LC|U8 ch
-Converts the specified character to lowercase using the current locale's rules,
-if possible; otherwise returns the input character itself.
-
=for apidoc Am|U8|toTITLE|U8 ch
Converts the specified character to titlecase. If the input is anything but an
ASCII lowercase character, that input character itself is returned. Variant
-C<toTITLE_A> is equivalent. (There is no C<toTITLE_L1> for the full Latin1 range,
-as the full generality of L</toTITLE_uni> is needed there. Titlecase is not a
-concept used in locale handling, so there is no functionality for that.)
+C<toTITLE_A> is equivalent. (There is no C<toTITLE_L1> for the full Latin1
+range, as the full generality of L</toTITLE_uni> is needed there. Titlecase is
+not a concept used in locale handling, so there is no functionality for that.)
=for apidoc Am|UV|toTITLE_uni|UV cp|U8* s|STRLEN* lenp
Converts the Unicode code point C<cp> to its titlecase version, and
* 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.
+ *
+ * For Coverity, be always true, because otherwise Coverity thinks
+ * it finds several expressions that are always true, independent
+ * of operands. Well, they are, but that is kind of the point.
*/
+#ifndef __COVERITY__
#define FITS_IN_8_BITS(c) ((sizeof(c) == 1) || !(((WIDEST_UTYPE)(c)) & ~0xFF))
+#else
+#define FITS_IN_8_BITS(c) (1)
+#endif
#ifdef EBCDIC
# ifndef _ALL_SOURCE
- /* This returns the wrong results on at least z/OS unless this is
- * defined. */
+ /* The native libc isascii() et.al. functions return the wrong results
+ * on at least z/OS unless this is defined. */
# error _ALL_SOURCE should probably be defined
# endif
-
- /* We could be called without perl.h, in which case NATIVE_TO_ASCII() is
- * likely not defined, and so we use the native function */
-# define isASCII(c) cBOOL(isascii(c))
#else
-# define isASCII(c) ((WIDEST_UTYPE)(c) < 128)
+ /* There is a simple definition of ASCII for ASCII platforms. But the
+ * EBCDIC one isn't so simple, so is defined using table look-up like the
+ * other macros below.
+ * The '| 0' part ensures that c is an integer (and not e.g. a pointer) */
+# define isASCII(c) ((WIDEST_UTYPE)((c) | 0) < 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. For internal core Perl use only. The ones less
* useful to group these which have no members that match above Latin1, (or
* above ASCII in the latter case) */
-# define _CC_SPACE 10 /* \s */
+# define _CC_SPACE 10 /* \s, [:space:] */
# define _CC_BLANK 11 /* [:blank:] */
# define _CC_XDIGIT 12 /* [:xdigit:] */
-# define _CC_PSXSPC 13 /* [:space:] */
-# define _CC_CNTRL 14 /* [:cntrl:] */
-# define _CC_ASCII 15 /* [:ascii:] */
-# define _CC_VERTSPACE 16 /* \v */
+# define _CC_CNTRL 13 /* [:cntrl:] */
+# define _CC_ASCII 14 /* [:ascii:] */
+# define _CC_VERTSPACE 15 /* \v */
# define _HIGHEST_REGCOMP_DOT_H_SYNC _CC_VERTSPACE
/* The members of the third group below do not need to be coordinated with data
* structures in regcomp.[ch] and regexec.c. */
-# define _CC_IDFIRST 17
-# define _CC_CHARNAME_CONT 18
-# define _CC_NONLATIN1_FOLD 19
-# define _CC_NONLATIN1_SIMPLE_FOLD 20
-# define _CC_QUOTEMETA 21
-# define _CC_NON_FINAL_FOLD 22
-# define _CC_IS_IN_SOME_FOLD 23
-/* Unused: 24-31
+# define _CC_IDFIRST 16
+# define _CC_CHARNAME_CONT 17
+# define _CC_NONLATIN1_FOLD 18
+# define _CC_NONLATIN1_SIMPLE_FOLD 19
+# define _CC_QUOTEMETA 20
+# define _CC_NON_FINAL_FOLD 21
+# define _CC_IS_IN_SOME_FOLD 22
+# define _CC_MNEMONIC_CNTRL 23
+
+/* This next group is only used on EBCDIC platforms, so theoretically could be
+ * shared with something entirely different that's only on ASCII platforms */
+# define _CC_UTF8_START_BYTE_IS_FOR_AT_LEAST_SURROGATE 28
+# define _CC_UTF8_IS_START 29
+# define _CC_UTF8_IS_DOWNGRADEABLE_START 30
+# define _CC_UTF8_IS_CONTINUATION 31
+/* Unused: 24-27
* 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. The IS_IN_SOME_FOLD bit is the most easily expendable, as it
* is used only for optimization (as of this writing), and differs in the
* Latin1 range from the ALPHA bit only in two relatively unimportant
* characters: the masculine and feminine ordinal indicators, so removing it
- * would just cause /i regexes which match them to run less efficiently */
+ * would just cause /i regexes which match them to run less efficiently.
+ * Similarly the EBCDIC-only bits are used just for speed, and could be
+ * replaced by other means */
#if defined(PERL_CORE) || defined(PERL_EXT)
/* An enum version of the character class numbers, to help compilers
_CC_ENUM_GRAPH = _CC_GRAPH,
_CC_ENUM_LOWER = _CC_LOWER,
_CC_ENUM_PRINT = _CC_PRINT,
- _CC_ENUM_PSXSPC = _CC_PSXSPC,
_CC_ENUM_PUNCT = _CC_PUNCT,
_CC_ENUM_SPACE = _CC_SPACE,
_CC_ENUM_UPPER = _CC_UPPER,
#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 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
};
#endif
+START_EXTERN_C
# ifdef DOINIT
EXTCONST U32 PL_charclass[] = {
# include "l1_char_class_tab.h"
# else /* ! DOINIT */
EXTCONST U32 PL_charclass[];
# endif
+END_EXTERN_C
/* The 1U keeps Solaris from griping when shifting sets the uppermost bit */
# define _CC_mask(classnum) (1U << (classnum))
/* For internal core Perl use only: the base macro for defining macros like
* isALPHA_A. The foo_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) (c)] & _CC_mask_A(classnum)) \
- == _CC_mask_A(classnum)))
+# define _generic_isCC_A(c, classnum) (FITS_IN_8_BITS(c) \
+ && ((PL_charclass[(U8) (c)] & _CC_mask_A(classnum)) \
+ == _CC_mask_A(classnum)))
# define isALPHA_A(c) _generic_isCC_A(c, _CC_ALPHA)
# define isALPHANUMERIC_A(c) _generic_isCC_A(c, _CC_ALPHANUMERIC)
# 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 isDIGIT_A(c) _generic_isCC(c, _CC_DIGIT) /* No non-ASCII digits */
# 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 isXDIGIT_A(c) _generic_isCC(c, _CC_XDIGIT) /* No non-ASCII xdigits
+ */
# define isIDFIRST_A(c) _generic_isCC_A(c, _CC_IDFIRST)
# define isALPHA_L1(c) _generic_isCC(c, _CC_ALPHA)
# define isALPHANUMERIC_L1(c) _generic_isCC(c, _CC_ALPHANUMERIC)
# 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 isPSXSPC_L1(c) isSPACE_L1(c)
# 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)
+# ifdef EBCDIC
+# define isASCII(c) _generic_isCC(c, _CC_ASCII)
+# endif
+
/* Participates in a single-character fold with a character above 255 */
# define _HAS_NONLATIN1_SIMPLE_FOLD_CLOSURE_ONLY_FOR_USE_BY_REGCOMP_DOT_C_AND_REGEXEC_DOT_C(c) ((! cBOOL(FITS_IN_8_BITS(c))) || (PL_charclass[(U8) (c)] & _CC_mask(_CC_NONLATIN1_SIMPLE_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)
+ _generic_isCC(c, _CC_NON_FINAL_FOLD)
# define _IS_IN_SOME_FOLD_ONLY_FOR_USE_BY_REGCOMP_DOT_C(c) \
- _generic_isCC(c, _CC_IS_IN_SOME_FOLD)
-#else /* else we don't have perl.h */
+ _generic_isCC(c, _CC_IS_IN_SOME_FOLD)
+# define _IS_MNEMONIC_CNTRL_ONLY_FOR_USE_BY_REGCOMP_DOT_C(c) \
+ _generic_isCC(c, _CC_MNEMONIC_CNTRL)
+#else /* else we don't have perl.h H_PERL */
/* If we don't have perl.h, we are compiling a utility program. Below we
* hard-code various macro definitions that wouldn't otherwise be available
- * to it. */
-# ifdef EBCDIC
- /* Use the native functions. They likely will return false for all
- * non-ASCII values, but this makes sure */
-# define isLOWER_A(c) (isASCII(c) && islower(c))
-# define isPRINT_A(c) (isASCII(c) && isprint(c))
-# define isUPPER_A(c) (isASCII(c) && isupper(c))
-# else /* ASCII platform. These are coded based on first principals */
+ * to it. Most are coded based on first principals. First some ones common
+ * to both ASCII and EBCDIC */
+# define isDIGIT_A(c) ((c) <= '9' && (c) >= '0')
+# define isBLANK_A(c) ((c) == ' ' || (c) == '\t')
+# define isSPACE_A(c) (isBLANK_A(c) \
+ || (c) == '\n' \
+ || (c) == '\r' \
+ || (c) == '\v' \
+ || (c) == '\f')
+# ifdef EBCDIC /* There are gaps between 'i' and 'j'; 'r' and 's'. Same
+ for uppercase. This is ordered to exclude most things
+ early */
+# define isLOWER_A(c) ((c) >= 'a' && (c) <= 'z' \
+ && ((c) <= 'i' \
+ || ((c) >= 'j' && (c) <= 'r') \
+ || (c) >= 's'))
+# define isUPPER_A(c) ((c) >= 'A' && (c) <= 'Z' \
+ && ((c) <= 'I' \
+ || ((c) >= 'J' && (c) <= 'R') \
+ || (c) >= 'S'))
+# else /* ASCII platform. */
# define isLOWER_A(c) ((c) >= 'a' && (c) <= 'z')
-# define isPRINT_A(c) (((c) >= 32 && (c) < 127))
# define isUPPER_A(c) ((c) <= 'Z' && (c) >= 'A')
-# endif /* Below are common definitions for ASCII and non-ASCII */
+# endif
+
+ /* Some more ASCII, non-ASCII common definitions */
# define isALPHA_A(c) (isUPPER_A(c) || isLOWER_A(c))
# define isALPHANUMERIC_A(c) (isALPHA_A(c) || isDIGIT_A(c))
-# define isBLANK_A(c) ((c) == ' ' || (c) == '\t')
-# define isCNTRL_A(c) (isASCII(c) && (! isPRINT_A(c)))
-# define isDIGIT_A(c) ((c) <= '9' && (c) >= '0')
-# define isGRAPH_A(c) (isPRINT_A(c) && (c) != ' ')
-# define isIDFIRST_A(c) (isALPHA_A(c) || (c) == '_')
-# define isPUNCT_A(c) (isGRAPH_A(c) && (! isALPHANUMERIC_A(c)))
-# define isSPACE_A(c) ((c) == ' ' \
- || (c) == '\t' \
- || (c) == '\n' \
- || (c) == '\r' \
- || (c) == '\v' \
- || (c) == '\f')
# define isWORDCHAR_A(c) (isALPHANUMERIC_A(c) || (c) == '_')
-# define isXDIGIT_A(c) (isDIGIT_A(c) \
- || ((c) >= 'a' && (c) <= 'f') \
+# define isIDFIRST_A(c) (isALPHA_A(c) || (c) == '_')
+# define isXDIGIT_A(c) (isDIGIT_A(c) \
+ || ((c) >= 'a' && (c) <= 'f') \
|| ((c) <= 'F' && (c) >= 'A'))
+# ifdef EBCDIC
+# define isPUNCT_A(c) ((c) == '-' || (c) == '!' || (c) == '"' \
+ || (c) == '#' || (c) == '$' || (c) == '%' \
+ || (c) == '&' || (c) == '\'' || (c) == '(' \
+ || (c) == ')' || (c) == '*' || (c) == '+' \
+ || (c) == ',' || (c) == '.' || (c) == '/' \
+ || (c) == ':' || (c) == ';' || (c) == '<' \
+ || (c) == '=' || (c) == '>' || (c) == '?' \
+ || (c) == '@' || (c) == '[' || (c) == '\\' \
+ || (c) == ']' || (c) == '^' || (c) == '_' \
+ || (c) == '`' || (c) == '{' || (c) == '|' \
+ || (c) == '}' || (c) == '~')
+# define isGRAPH_A(c) (isALPHANUMERIC_A(c) || isPUNCT_A(c))
+# define isPRINT_A(c) (isGRAPH_A(c) || (c) == ' ')
+
+# ifdef QUESTION_MARK_CTRL
+# define _isQMC(c) ((c) == QUESTION_MARK_CTRL)
+# else
+# define _isQMC(c) 0
+# endif
+
+ /* I (khw) can't think of a way to define all the ASCII controls
+ * without resorting to a libc (locale-sensitive) call. But we know
+ * that all controls but the question-mark one are in the range 0-0x3f.
+ * This makes sure that all the controls that have names are included,
+ * and all controls that are also considered ASCII in the locale. This
+ * may include more or fewer than what it actually should, but the
+ * wrong ones are less-important controls, so likely won't impact
+ * things (keep in mind that this is compiled only if perl.h isn't
+ * available). The question mark control is included if available */
+# define isCNTRL_A(c) (((c) < 0x40 && isascii(c)) \
+ || (c) == '\0' || (c) == '\a' || (c) == '\b' \
+ || (c) == '\f' || (c) == '\n' || (c) == '\r' \
+ || (c) == '\t' || (c) == '\v' || _isQMC(c))
+
+# define isASCII(c) (isCNTRL_A(c) || isPRINT_A(c))
+# else /* ASCII platform; things are simpler, and isASCII has already
+ been defined */
+# define isGRAPH_A(c) (((c) > ' ' && (c) < 127))
+# define isPRINT_A(c) (isGRAPH_A(c) || (c) == ' ')
+# define isPUNCT_A(c) (isGRAPH_A(c) && (! isALPHANUMERIC_A(c)))
+# define isCNTRL_A(c) (isASCII(c) && (! isPRINT_A(c)))
+# endif
+
/* The _L1 macros may be unnecessary for the utilities; I (khw) added them
- * during debugging, and it seems best to keep them. */
-# define isPSXSPC_A(c) isSPACE_A(c) /* XXX Assumes SPACE matches '\v' */
+ * during debugging, and it seems best to keep them. We may be called
+ * without NATIVE_TO_LATIN1 being defined. On ASCII platforms, it doesn't
+ * do anything anyway, so make it not a problem */
+# if ! defined(EBCDIC) && ! defined(NATIVE_TO_LATIN1)
+# define NATIVE_TO_LATIN1(ch) (ch)
+# endif
# define isALPHA_L1(c) (isUPPER_L1(c) || isLOWER_L1(c))
# define isALPHANUMERIC_L1(c) (isALPHA_L1(c) || isDIGIT_A(c))
# define isBLANK_L1(c) (isBLANK_A(c) \
# define isPRINT_L1(c) (isPRINT_A(c) \
|| (FITS_IN_8_BITS(c) \
&& NATIVE_TO_LATIN1((U8) c) >= 0xA0))
-# define isPSXSPC_L1(c) isSPACE_L1(c)
# define isPUNCT_L1(c) (isPUNCT_A(c) \
|| (FITS_IN_8_BITS(c) \
&& (NATIVE_TO_LATIN1((U8) c) == 0xA1 \
/* And these aren't accurate at all. They are useful only for above
* Latin1, which utilities and bootstrapping don't deal with */
# define _IS_NON_FINAL_FOLD_ONLY_FOR_USE_BY_REGCOMP_DOT_C(c) 0
+# define _HAS_NONLATIN1_SIMPLE_FOLD_CLOSURE_ONLY_FOR_USE_BY_REGCOMP_DOT_C_AND_REGEXEC_DOT_C(c) 0
# define _HAS_NONLATIN1_FOLD_CLOSURE_ONLY_FOR_USE_BY_REGCOMP_DOT_C_AND_REGEXEC_DOT_C(c) 0
/* Many of the macros later in this file are defined in terms of these. By
(FITS_IN_8_BITS(c) && S_bootstrap_ctype((U8) (c), (classnum), TRUE))
# define _generic_isCC_A(c, classnum) \
(FITS_IN_8_BITS(c) && S_bootstrap_ctype((U8) (c), (classnum), FALSE))
-#endif /* End of no perl.h */
+#endif /* End of no perl.h H_PERL */
#define isALPHANUMERIC(c) isALPHANUMERIC_A(c)
#define isALPHA(c) isALPHA_A(c)
+#define isASCII_A(c) isASCII(c)
+#define isASCII_L1(c) isASCII(c)
#define isBLANK(c) isBLANK_A(c)
#define isCNTRL(c) isCNTRL_A(c)
#define isDIGIT(c) isDIGIT_A(c)
#define isIDFIRST(c) isIDFIRST_A(c)
#define isLOWER(c) isLOWER_A(c)
#define isPRINT(c) isPRINT_A(c)
+#define isPSXSPC_A(c) isSPACE_A(c)
#define isPSXSPC(c) isPSXSPC_A(c)
+#define isPSXSPC_L1(c) isSPACE_L1(c)
#define isPUNCT(c) isPUNCT_A(c)
#define isSPACE(c) isSPACE_A(c)
#define isUPPER(c) isUPPER_A(c)
? (c) \
: (IN_UTF8_CTYPE_LOCALE) \
? PL_latin1_lc[ (U8) (c) ] \
- : function((cast)(c)))
+ : (cast)function((cast)(c)))
/* Note that the result can be larger than a byte in a UTF-8 locale. It
* returns a single value, so can't adequately return the upper case of LATIN
(! FITS_IN_8_BITS(c) \
? (c) \
: ((! IN_UTF8_CTYPE_LOCALE) \
- ? function((cast)(c)) \
+ ? (cast)function((cast)(c)) \
: ((((U8)(c)) == MICRO_SIGN) \
? GREEK_CAPITAL_LETTER_MU \
: ((((U8)(c)) == LATIN_SMALL_LETTER_Y_WITH_DIAERESIS) \
#if defined(HAS_ISBLANK)
# define isBLANK_LC(c) _generic_LC(c, _CC_BLANK, isblank)
#else /* Unlike isASCII, varies if in a UTF-8 locale */
-# define isBLANK_LC(c) (IN_UTF8_CTYPE_LOCALE) ? isBLANK_L1(c) : isBLANK(c)
+# define isBLANK_LC(c) ((IN_UTF8_CTYPE_LOCALE) ? isBLANK_L1(c) : isBLANK(c))
#endif
#define _LC_CAST U8
* Not all possible weirdnesses are checked for, just the ones that were
* detected on actual Microsoft code pages */
-# define isCNTRL_LC(c) _generic_LC(c, _CC_CNTRL, iscntrl)
-# define isSPACE_LC(c) _generic_LC(c, _CC_SPACE, isspace)
-
-# define isALPHA_LC(c) (_generic_LC(c, _CC_ALPHA, isalpha) && isALPHANUMERIC_LC(c))
-# define isALPHANUMERIC_LC(c) (_generic_LC(c, _CC_ALPHANUMERIC, isalnum) && ! isPUNCT_LC(c))
-# define isDIGIT_LC(c) (_generic_LC(c, _CC_DIGIT, isdigit) && isALPHANUMERIC_LC(c))
-# define isGRAPH_LC(c) (_generic_LC(c, _CC_GRAPH, isgraph) && isPRINT_LC(c))
-# define isIDFIRST_LC(c) (((c) == '_') || (_generic_LC(c, _CC_IDFIRST, isalpha) && ! isPUNCT_LC(c)))
-# define isLOWER_LC(c) (_generic_LC(c, _CC_LOWER, islower) && isALPHA_LC(c))
-# define isPRINT_LC(c) (_generic_LC(c, _CC_PRINT, isprint) && ! isCNTRL_LC(c))
-# define isPUNCT_LC(c) (_generic_LC(c, _CC_PUNCT, ispunct) && ! isCNTRL_LC(c))
-# define isUPPER_LC(c) (_generic_LC(c, _CC_UPPER, isupper) && isALPHA_LC(c))
+# define isCNTRL_LC(c) _generic_LC(c, _CC_CNTRL, iscntrl)
+# define isSPACE_LC(c) _generic_LC(c, _CC_SPACE, isspace)
+
+# define isALPHA_LC(c) (_generic_LC(c, _CC_ALPHA, isalpha) \
+ && isALPHANUMERIC_LC(c))
+# define isALPHANUMERIC_LC(c) (_generic_LC(c, _CC_ALPHANUMERIC, isalnum) && \
+ ! isPUNCT_LC(c))
+# define isDIGIT_LC(c) (_generic_LC(c, _CC_DIGIT, isdigit) && \
+ isALPHANUMERIC_LC(c))
+# define isGRAPH_LC(c) (_generic_LC(c, _CC_GRAPH, isgraph) && isPRINT_LC(c))
+# define isIDFIRST_LC(c) (((c) == '_') \
+ || (_generic_LC(c, _CC_IDFIRST, isalpha) && ! isPUNCT_LC(c)))
+# define isLOWER_LC(c) (_generic_LC(c, _CC_LOWER, islower) && isALPHA_LC(c))
+# define isPRINT_LC(c) (_generic_LC(c, _CC_PRINT, isprint) && ! isCNTRL_LC(c))
+# define isPUNCT_LC(c) (_generic_LC(c, _CC_PUNCT, ispunct) && ! isCNTRL_LC(c))
+# define isUPPER_LC(c) (_generic_LC(c, _CC_UPPER, isupper) && isALPHA_LC(c))
# define isWORDCHAR_LC(c) (((c) == '_') || isALPHANUMERIC_LC(c))
-# define isXDIGIT_LC(c) (_generic_LC(c, _CC_XDIGIT, isxdigit) && isALPHANUMERIC_LC(c))
+# define isXDIGIT_LC(c) (_generic_LC(c, _CC_XDIGIT, isxdigit) \
+ && isALPHANUMERIC_LC(c))
# define toLOWER_LC(c) _generic_toLOWER_LC((c), tolower, U8)
# define toUPPER_LC(c) _generic_toUPPER_LC((c), toupper, U8)
#else /* The final fallback position */
-# define isALPHA_LC(c) (isascii(c) && isalpha(c))
-# define isALPHANUMERIC_LC(c) (isascii(c) && isalnum(c))
-# define isCNTRL_LC(c) (isascii(c) && iscntrl(c))
-# define isDIGIT_LC(c) (isascii(c) && isdigit(c))
-# define isGRAPH_LC(c) (isascii(c) && isgraph(c))
+# define isALPHA_LC(c) (isascii(c) && isalpha(c))
+# define isALPHANUMERIC_LC(c) (isascii(c) && isalnum(c))
+# define isCNTRL_LC(c) (isascii(c) && iscntrl(c))
+# define isDIGIT_LC(c) (isascii(c) && isdigit(c))
+# define isGRAPH_LC(c) (isascii(c) && isgraph(c))
# define isIDFIRST_LC(c) (isascii(c) && (isalpha(c) || (c) == '_'))
-# define isLOWER_LC(c) (isascii(c) && islower(c))
-# define isPRINT_LC(c) (isascii(c) && isprint(c))
-# define isPUNCT_LC(c) (isascii(c) && ispunct(c))
-# define isSPACE_LC(c) (isascii(c) && isspace(c))
-# define isUPPER_LC(c) (isascii(c) && isupper(c))
+# define isLOWER_LC(c) (isascii(c) && islower(c))
+# define isPRINT_LC(c) (isascii(c) && isprint(c))
+# define isPUNCT_LC(c) (isascii(c) && ispunct(c))
+# define isSPACE_LC(c) (isascii(c) && isspace(c))
+# define isUPPER_LC(c) (isascii(c) && isupper(c))
# define isWORDCHAR_LC(c) (isascii(c) && (isalnum(c) || (c) == '_'))
-# define isXDIGIT_LC(c) (isascii(c) && isxdigit(c))
+# define isXDIGIT_LC(c) (isascii(c) && isxdigit(c))
# define toLOWER_LC(c) (isascii(c) ? tolower(c) : (c))
# define toUPPER_LC(c) (isascii(c) ? toupper(c) : (c))
#define isLOWER_uni(c) _generic_swash_uni(_CC_LOWER, c)
#define isPRINT_uni(c) _generic_swash_uni(_CC_PRINT, c)
-/* Posix and regular space are identical above Latin1 */
-#define isPSXSPC_uni(c) _generic_uni(_CC_PSXSPC, is_XPERLSPACE_cp_high, c)
-
#define isPUNCT_uni(c) _generic_swash_uni(_CC_PUNCT, c)
#define isSPACE_uni(c) _generic_uni(_CC_SPACE, is_XPERLSPACE_cp_high, c)
+#define isPSXSPC_uni(c) isSPACE_uni(c)
+
#define isUPPER_uni(c) _generic_swash_uni(_CC_UPPER, c)
#define isVERTWS_uni(c) _generic_uni(_CC_VERTSPACE, is_VERTWS_cp_high, c)
#define isWORDCHAR_uni(c) _generic_swash_uni(_CC_WORDCHAR, c)
#define isALPHA_LC_uvchr(c) _generic_LC_swash_uvchr(isALPHA_LC, _CC_ALPHA, c)
#define isALPHANUMERIC_LC_uvchr(c) _generic_LC_swash_uvchr(isALPHANUMERIC_LC, \
_CC_ALPHANUMERIC, c)
-#define isASCII_LC_uvchr(c) isASCII_LC(c)
-#define isBLANK_LC_uvchr(c) _generic_LC_uvchr(isBLANK_LC, is_HORIZWS_cp_high, c)
+#define isASCII_LC_uvchr(c) isASCII_LC(c)
+#define isBLANK_LC_uvchr(c) _generic_LC_uvchr(isBLANK_LC, \
+ is_HORIZWS_cp_high, c)
#define isCNTRL_LC_uvchr(c) (c < 256 ? isCNTRL_LC(c) : 0)
#define isDIGIT_LC_uvchr(c) _generic_LC_swash_uvchr(isDIGIT_LC, _CC_DIGIT, c)
#define isGRAPH_LC_uvchr(c) _generic_LC_swash_uvchr(isGRAPH_LC, _CC_GRAPH, c)
-#define isIDCONT_LC_uvchr(c) _generic_LC_uvchr(isIDCONT_LC, \
+#define isIDCONT_LC_uvchr(c) _generic_LC_uvchr(isIDCONT_LC, \
_is_uni_perl_idcont, c)
-#define isIDFIRST_LC_uvchr(c) _generic_LC_uvchr(isIDFIRST_LC, \
+#define isIDFIRST_LC_uvchr(c) _generic_LC_uvchr(isIDFIRST_LC, \
_is_uni_perl_idstart, c)
#define isLOWER_LC_uvchr(c) _generic_LC_swash_uvchr(isLOWER_LC, _CC_LOWER, c)
#define isPRINT_LC_uvchr(c) _generic_LC_swash_uvchr(isPRINT_LC, _CC_PRINT, c)
-#define isPSXSPC_LC_uvchr(c) isSPACE_LC_uvchr(c) /* space is identical to posix
- space under locale */
+#define isPSXSPC_LC_uvchr(c) isSPACE_LC_uvchr(c)
#define isPUNCT_LC_uvchr(c) _generic_LC_swash_uvchr(isPUNCT_LC, _CC_PUNCT, c)
-#define isSPACE_LC_uvchr(c) _generic_LC_uvchr(isSPACE_LC, \
+#define isSPACE_LC_uvchr(c) _generic_LC_uvchr(isSPACE_LC, \
is_XPERLSPACE_cp_high, c)
#define isUPPER_LC_uvchr(c) _generic_LC_swash_uvchr(isUPPER_LC, _CC_UPPER, c)
-#define isWORDCHAR_LC_uvchr(c) _generic_LC_swash_uvchr(isWORDCHAR_LC, \
+#define isWORDCHAR_LC_uvchr(c) _generic_LC_swash_uvchr(isWORDCHAR_LC, \
_CC_WORDCHAR, c)
-#define isXDIGIT_LC_uvchr(c) _generic_LC_uvchr(isXDIGIT_LC, is_XDIGIT_cp_high, c)
+#define isXDIGIT_LC_uvchr(c) _generic_LC_uvchr(isXDIGIT_LC, \
+ is_XDIGIT_cp_high, c)
-#define isBLANK_LC_uni(c) isBLANK_LC_uvchr(UNI_TO_NATIVE(c))
+#define isBLANK_LC_uni(c) isBLANK_LC_uvchr(UNI_TO_NATIVE(c))
/* For internal core Perl use only: the base macros for defining macros like
* isALPHA_utf8. These are like the earlier defined macros, but take an input
? _generic_isCC(*(p), classnum) \
: (UTF8_IS_DOWNGRADEABLE_START(*(p))) \
? _generic_isCC( \
- TWO_BYTE_UTF8_TO_NATIVE(*(p), \
+ EIGHT_BIT_UTF8_TO_NATIVE(*(p), \
*((p)+1 )), \
classnum) \
: utf8)
-/* Like the above, but calls 'above_latin1(p)' to get the utf8 value. 'above_latin1'
- * can be a macro */
+/* Like the above, but calls 'above_latin1(p)' to get the utf8 value.
+ * 'above_latin1' can be a macro */
#define _generic_func_utf8(classnum, above_latin1, p) \
_generic_utf8(classnum, p, above_latin1(p))
/* Like the above, but passes classnum to _isFOO_utf8(), instead of having an
* points; the regcharclass.h ones are implemented as a series of
* "if-else-if-else ..." */
-#define isALPHA_utf8(p) _generic_swash_utf8(_CC_ALPHA, p)
-#define isALPHANUMERIC_utf8(p) _generic_swash_utf8(_CC_ALPHANUMERIC, p)
-#define isASCII_utf8(p) isASCII(*p) /* Because ASCII is invariant under
+#define isALPHA_utf8(p) _generic_swash_utf8(_CC_ALPHA, p)
+#define isALPHANUMERIC_utf8(p) _generic_swash_utf8(_CC_ALPHANUMERIC, p)
+#define isASCII_utf8(p) isASCII(*p) /* Because ASCII is invariant under
utf8, the non-utf8 macro works
*/
-#define isBLANK_utf8(p) _generic_func_utf8(_CC_BLANK, is_HORIZWS_high, p)
+#define isBLANK_utf8(p) _generic_func_utf8(_CC_BLANK, is_HORIZWS_high, p)
#ifdef EBCDIC
/* Because all controls are UTF-8 invariants in EBCDIC, we can use this
* more efficient macro instead of the more general one */
-# define isCNTRL_utf8(p) isCNTRL_L1(p)
+# define isCNTRL_utf8(p) isCNTRL_L1(*(p))
#else
# define isCNTRL_utf8(p) _generic_utf8(_CC_CNTRL, p, 0)
#endif
* ever wanted to know about. (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) _generic_func_utf8(_CC_IDFIRST, \
+#define isIDFIRST_utf8(p) _generic_func_utf8(_CC_IDFIRST, \
_is_utf8_perl_idstart, p)
-#define isLOWER_utf8(p) _generic_swash_utf8(_CC_LOWER, p)
-#define isPRINT_utf8(p) _generic_swash_utf8(_CC_PRINT, p)
-
-/* Posix and regular space are identical above Latin1 */
-#define isPSXSPC_utf8(p) _generic_func_utf8(_CC_PSXSPC, is_XPERLSPACE_high, p)
-
-#define isPUNCT_utf8(p) _generic_swash_utf8(_CC_PUNCT, p)
-#define isSPACE_utf8(p) _generic_func_utf8(_CC_SPACE, is_XPERLSPACE_high, p)
-#define isUPPER_utf8(p) _generic_swash_utf8(_CC_UPPER, p)
-#define isVERTWS_utf8(p) _generic_func_utf8(_CC_VERTSPACE, is_VERTWS_high, p)
-#define isWORDCHAR_utf8(p) _generic_swash_utf8(_CC_WORDCHAR, p)
-#define isXDIGIT_utf8(p) _generic_utf8_no_upper_latin1(_CC_XDIGIT, p, \
+#define isLOWER_utf8(p) _generic_swash_utf8(_CC_LOWER, p)
+#define isPRINT_utf8(p) _generic_swash_utf8(_CC_PRINT, p)
+#define isPSXSPC_utf8(p) isSPACE_utf8(p)
+#define isPUNCT_utf8(p) _generic_swash_utf8(_CC_PUNCT, p)
+#define isSPACE_utf8(p) _generic_func_utf8(_CC_SPACE, is_XPERLSPACE_high, p)
+#define isUPPER_utf8(p) _generic_swash_utf8(_CC_UPPER, p)
+#define isVERTWS_utf8(p) _generic_func_utf8(_CC_VERTSPACE, is_VERTWS_high, p)
+#define isWORDCHAR_utf8(p) _generic_swash_utf8(_CC_WORDCHAR, p)
+#define isXDIGIT_utf8(p) _generic_utf8_no_upper_latin1(_CC_XDIGIT, p, \
is_XDIGIT_high(p))
#define toFOLD_utf8(p,s,l) to_utf8_fold(p,s,l)
(UTF8_IS_INVARIANT(*(p)) \
? macro(*(p)) \
: (UTF8_IS_DOWNGRADEABLE_START(*(p))) \
- ? macro(TWO_BYTE_UTF8_TO_NATIVE(*(p), *((p)+1))) \
+ ? macro(EIGHT_BIT_UTF8_TO_NATIVE(*(p), *((p)+1)))\
: utf8)
#define _generic_LC_swash_utf8(macro, classnum, p) \
#define _generic_LC_func_utf8(macro, above_latin1, p) \
_generic_LC_utf8(macro, p, above_latin1(p))
-#define isALPHANUMERIC_LC_utf8(p) _generic_LC_swash_utf8(isALPHANUMERIC_LC, \
+#define isALPHANUMERIC_LC_utf8(p) _generic_LC_swash_utf8(isALPHANUMERIC_LC, \
_CC_ALPHANUMERIC, p)
-#define isALPHA_LC_utf8(p) _generic_LC_swash_utf8(isALPHA_LC, _CC_ALPHA, p)
-#define isASCII_LC_utf8(p) isASCII_LC(*p)
-#define isBLANK_LC_utf8(p) _generic_LC_func_utf8(isBLANK_LC, is_HORIZWS_high, p)
-#define isCNTRL_LC_utf8(p) _generic_LC_utf8(isCNTRL_LC, p, 0)
-#define isDIGIT_LC_utf8(p) _generic_LC_swash_utf8(isDIGIT_LC, _CC_DIGIT, p)
-#define isGRAPH_LC_utf8(p) _generic_LC_swash_utf8(isGRAPH_LC, _CC_GRAPH, p)
-#define isIDCONT_LC_utf8(p) _generic_LC_func_utf8(isIDCONT_LC, _is_utf8_perl_idcont, p)
-#define isIDFIRST_LC_utf8(p) _generic_LC_func_utf8(isIDFIRST_LC, _is_utf8_perl_idstart, p)
-#define isLOWER_LC_utf8(p) _generic_LC_swash_utf8(isLOWER_LC, _CC_LOWER, p)
-#define isPRINT_LC_utf8(p) _generic_LC_swash_utf8(isPRINT_LC, _CC_PRINT, p)
-#define isPSXSPC_LC_utf8(p) isSPACE_LC_utf8(p) /* space is identical to posix
- space under locale */
-#define isPUNCT_LC_utf8(p) _generic_LC_swash_utf8(isPUNCT_LC, _CC_PUNCT, p)
-#define isSPACE_LC_utf8(p) _generic_LC_func_utf8(isSPACE_LC, is_XPERLSPACE_high, p)
-#define isUPPER_LC_utf8(p) _generic_LC_swash_utf8(isUPPER_LC, _CC_UPPER, p)
+#define isALPHA_LC_utf8(p) _generic_LC_swash_utf8(isALPHA_LC, _CC_ALPHA, p)
+#define isASCII_LC_utf8(p) isASCII_LC(*p)
+#define isBLANK_LC_utf8(p) _generic_LC_func_utf8(isBLANK_LC, \
+ is_HORIZWS_high, p)
+#define isCNTRL_LC_utf8(p) _generic_LC_utf8(isCNTRL_LC, p, 0)
+#define isDIGIT_LC_utf8(p) _generic_LC_swash_utf8(isDIGIT_LC, _CC_DIGIT, p)
+#define isGRAPH_LC_utf8(p) _generic_LC_swash_utf8(isGRAPH_LC, _CC_GRAPH, p)
+#define isIDCONT_LC_utf8(p) _generic_LC_func_utf8(isIDCONT_LC, \
+ _is_utf8_perl_idcont, p)
+#define isIDFIRST_LC_utf8(p) _generic_LC_func_utf8(isIDFIRST_LC, \
+ _is_utf8_perl_idstart, p)
+#define isLOWER_LC_utf8(p) _generic_LC_swash_utf8(isLOWER_LC, _CC_LOWER, p)
+#define isPRINT_LC_utf8(p) _generic_LC_swash_utf8(isPRINT_LC, _CC_PRINT, p)
+#define isPSXSPC_LC_utf8(p) isSPACE_LC_utf8(p)
+#define isPUNCT_LC_utf8(p) _generic_LC_swash_utf8(isPUNCT_LC, _CC_PUNCT, p)
+#define isSPACE_LC_utf8(p) _generic_LC_func_utf8(isSPACE_LC, \
+ is_XPERLSPACE_high, p)
+#define isUPPER_LC_utf8(p) _generic_LC_swash_utf8(isUPPER_LC, _CC_UPPER, p)
#define isWORDCHAR_LC_utf8(p) _generic_LC_swash_utf8(isWORDCHAR_LC, \
_CC_WORDCHAR, p)
-#define isXDIGIT_LC_utf8(p) _generic_LC_func_utf8(isXDIGIT_LC, is_XDIGIT_high, p)
+#define isXDIGIT_LC_utf8(p) _generic_LC_func_utf8(isXDIGIT_LC, \
+ is_XDIGIT_high, p)
/* Macros for backwards compatibility and for completeness when the ASCII and
* Latin1 values are identical */
-#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)
-#define isALNUM(c) isWORDCHAR(c)
-#define isALNUMU(c) isWORDCHAR_L1(c)
-#define isALNUM_LC(c) isWORDCHAR_LC(c)
-#define isALNUM_uni(c) isWORDCHAR_uni(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)
+#define isALNUM(c) isWORDCHAR(c)
+#define isALNUMU(c) isWORDCHAR_L1(c)
+#define isALNUM_LC(c) isWORDCHAR_LC(c)
+#define isALNUM_uni(c) isWORDCHAR_uni(c)
#define isALNUM_LC_uvchr(c) isWORDCHAR_LC_uvchr(c)
-#define isALNUM_utf8(p) isWORDCHAR_utf8(p)
-#define isALNUM_LC_utf8(p) isWORDCHAR_LC_utf8(p)
-#define isALNUMC_A(c) isALPHANUMERIC_A(c) /* Mnemonic: "C's alnum" */
-#define isALNUMC_L1(c) isALPHANUMERIC_L1(c)
-#define isALNUMC(c) isALPHANUMERIC(c)
-#define isALNUMC_LC(c) isALPHANUMERIC_LC(c)
-#define isALNUMC_uni(c) isALPHANUMERIC_uni(c)
+#define isALNUM_utf8(p) isWORDCHAR_utf8(p)
+#define isALNUM_LC_utf8(p) isWORDCHAR_LC_utf8(p)
+#define isALNUMC_A(c) isALPHANUMERIC_A(c) /* Mnemonic: "C's alnum" */
+#define isALNUMC_L1(c) isALPHANUMERIC_L1(c)
+#define isALNUMC(c) isALPHANUMERIC(c)
+#define isALNUMC_LC(c) isALPHANUMERIC_LC(c)
+#define isALNUMC_uni(c) isALPHANUMERIC_uni(c)
#define isALNUMC_LC_uvchr(c) isALPHANUMERIC_LC_uvchr(c)
-#define isALNUMC_utf8(p) isALPHANUMERIC_utf8(p)
+#define isALNUMC_utf8(p) isALPHANUMERIC_utf8(p)
#define isALNUMC_LC_utf8(p) isALPHANUMERIC_LC_utf8(p)
/* On EBCDIC platforms, CTRL-@ is 0, CTRL-A is 1, etc, just like on ASCII,
* the outlier from the block that contains the other controls, just like
* toCTRL('?') on ASCII yields DEL, the control that is the outlier from the C0
* block. If it weren't special cased, it would yield a non-control.
- * The conversion works both ways, so CTRL('D') is 4, and CTRL(4) is D, etc. */
+ * The conversion works both ways, so toCTRL('D') is 4, and toCTRL(4) is D,
+ * etc. */
#ifndef EBCDIC
-# define toCTRL(c) (toUPPER(c) ^ 64)
+# define toCTRL(c) (__ASSERT_(FITS_IN_8_BITS(c)) toUPPER(((U8)(c))) ^ 64)
#else
-# define toCTRL(c) ((isPRINT_A(c)) \
- ? UNLIKELY((c) == '?') \
- ? QUESTION_MARK_CTRL \
- : (NATIVE_TO_LATIN1(toUPPER(c)) ^ 64) \
- : UNLIKELY((c) == QUESTION_MARK_CTRL) \
- ? ((c) == '?') \
- : (LATIN1_TO_NATIVE((c) ^ 64)))
+# define toCTRL(c) (__ASSERT_(FITS_IN_8_BITS(c)) \
+ ((isPRINT_A(c)) \
+ ? (UNLIKELY((c) == '?') \
+ ? QUESTION_MARK_CTRL \
+ : (NATIVE_TO_LATIN1(toUPPER((U8) (c))) ^ 64)) \
+ : (UNLIKELY((c) == QUESTION_MARK_CTRL) \
+ ? '?' \
+ : (LATIN1_TO_NATIVE(((U8) (c)) ^ 64)))))
#endif
/* Line numbers are unsigned, 32 bits. */
* compiler, this reduces to an AND and a TEST. On both EBCDIC and ASCII
* machines, 'A' and 'a' differ by a single bit; the same with the upper and
* lower case of all other ASCII-range alphabetics. On ASCII platforms, they
- * are 32 apart; on EBCDIC, they are 64. This uses an exclusive 'or' to find
- * that bit and then inverts it to form a mask, with just a single 0, in the
- * bit position where the upper- and lowercase differ. */
+ * are 32 apart; on EBCDIC, they are 64. At compile time, this uses an
+ * exclusive 'or' to find that bit and then inverts it to form a mask, with
+ * just a single 0, in the bit position where the upper- and lowercase differ.
+ * */
#define isALPHA_FOLD_EQ(c1, c2) \
(__ASSERT_(isALPHA_A(c1) || isALPHA_A(c2)) \
((c1) & ~('A' ^ 'a')) == ((c2) & ~('A' ^ 'a')))
=for apidoc Am|void|Newxc|void* ptr|int nitems|type|cast
The XSUB-writer's interface to the C C<malloc> function, with
-cast. See also C<Newx>.
+cast. See also C<L</Newx>>.
Memory obtained by this should B<ONLY> be freed with L<"Safefree">.
=for apidoc Am|void|Newxz|void* ptr|int nitems|type
The XSUB-writer's interface to the C C<malloc> function. The allocated
-memory is zeroed with C<memzero>. See also C<Newx>.
+memory is zeroed with C<memzero>. See also C<L</Newx>>.
Memory obtained by this should B<ONLY> be freed with L<"Safefree">.
=for apidoc Am|void|Move|void* src|void* dest|int nitems|type
The XSUB-writer's interface to the C C<memmove> function. The C<src> is the
source, C<dest> is the destination, C<nitems> is the number of items, and
-C<type> is the type. Can do overlapping moves. See also C<Copy>.
+C<type> is the type. Can do overlapping moves. See also C<L</Copy>>.
=for apidoc Am|void *|MoveD|void* src|void* dest|int nitems|type
-Like C<Move> but returns dest. Useful
+Like C<Move> but returns C<dest>. Useful
for encouraging compilers to tail-call
optimise.
=for apidoc Am|void|Copy|void* src|void* dest|int nitems|type
The XSUB-writer's interface to the C C<memcpy> function. The C<src> is the
source, C<dest> is the destination, C<nitems> is the number of items, and
-C<type> is the type. May fail on overlapping copies. See also C<Move>.
+C<type> is the type. May fail on overlapping copies. See also C<L</Move>>.
=for apidoc Am|void *|CopyD|void* src|void* dest|int nitems|type
-Like C<Copy> but returns dest. Useful
+Like C<Copy> but returns C<dest>. Useful
for encouraging compilers to tail-call
optimise.
#define MEM_SIZE_MAX ((MEM_SIZE)~0)
-/* The +0.0 in MEM_WRAP_CHECK_ is an attempt to foil
- * overly eager compilers that will bleat about e.g.
- * (U16)n > (size_t)~0/sizeof(U16) always being false. */
+
#ifdef PERL_MALLOC_WRAP
-#define MEM_WRAP_CHECK(n,t) \
- (void)(UNLIKELY(sizeof(t) > 1 && ((MEM_SIZE)(n)+0.0) > MEM_SIZE_MAX/sizeof(t)) && (croak_memory_wrap(),0))
-#define MEM_WRAP_CHECK_1(n,t,a) \
- (void)(UNLIKELY(sizeof(t) > 1 && ((MEM_SIZE)(n)+0.0) > MEM_SIZE_MAX/sizeof(t)) && (Perl_croak_nocontext("%s",(a)),0))
+
+/* This expression will be constant-folded at compile time. It checks
+ * whether or not the type of the count n is so small (e.g. U8 or U16, or
+ * U32 on 64-bit systems) that there's no way a wrap-around could occur.
+ * As well as avoiding the need for a run-time check in some cases, it's
+ * designed to avoid compiler warnings like:
+ * comparison is always false due to limited range of data type
+ * It's mathematically equivalent to
+ * max(n) * sizeof(t) > MEM_SIZE_MAX
+ */
+
+# define _MEM_WRAP_NEEDS_RUNTIME_CHECK(n,t) \
+ ( 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
+ * _MEM_WRAP_NEEDS_RUNTIME_CHECK(n,t) && (n > C)
+ * (for some compile-time constant C), but even when the LHS
+ * constant-folds to false at compile-time, g++ insists on emitting
+ * warnings about the RHS (e.g. "comparison is always false"), so instead
+ * we write it as
+ *
+ * (cond ? n : X) > C
+ *
+ * where X is a constant with X > C always false. Choosing a value for X
+ * is tricky. If 0, some compilers will complain about 0 > C always being
+ * false; if 1, Coverity complains when n happens to be the constant value
+ * '1', that cond ? 1 : 1 has the same value on both branches; so use C
+ * for X and hope that nothing else whines.
+ */
+
+# define _MEM_WRAP_WILL_WRAP(n,t) \
+ ((_MEM_WRAP_NEEDS_RUNTIME_CHECK(n,t) ? (MEM_SIZE)(n) : \
+ MEM_SIZE_MAX/sizeof(t)) > MEM_SIZE_MAX/sizeof(t))
+
+# define MEM_WRAP_CHECK(n,t) \
+ (void)(UNLIKELY(_MEM_WRAP_WILL_WRAP(n,t)) \
+ && (croak_memory_wrap(),0))
+
+# define MEM_WRAP_CHECK_1(n,t,a) \
+ (void)(UNLIKELY(_MEM_WRAP_WILL_WRAP(n,t)) \
+ && (Perl_croak_nocontext("%s",(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),((n-1+PERL_STRLEN_ROUNDUP_QUANTUM)&~((MEM_SIZE)PERL_STRLEN_ROUNDUP_QUANTUM-1)))
* - lots of ENV reads
*/
-PERL_EXPORT_C Malloc_t Perl_mem_log_alloc(const UV n, const UV typesize, const char *type_name, Malloc_t newalloc, const char *filename, const int linenumber, const char *funcname);
+PERL_CALLCONV Malloc_t Perl_mem_log_alloc(const UV n, const UV typesize, const char *type_name, Malloc_t newalloc, const char *filename, const int linenumber, const char *funcname);
-PERL_EXPORT_C Malloc_t Perl_mem_log_realloc(const UV n, const UV typesize, const char *type_name, Malloc_t oldalloc, Malloc_t newalloc, const char *filename, const int linenumber, const char *funcname);
+PERL_CALLCONV Malloc_t Perl_mem_log_realloc(const UV n, const UV typesize, const char *type_name, Malloc_t oldalloc, Malloc_t newalloc, const char *filename, const int linenumber, const char *funcname);
-PERL_EXPORT_C Malloc_t Perl_mem_log_free(Malloc_t oldalloc, const char *filename, const int linenumber, const char *funcname);
+PERL_CALLCONV Malloc_t Perl_mem_log_free(Malloc_t oldalloc, const char *filename, const int linenumber, const char *funcname);
# ifdef PERL_CORE
# ifndef PERL_MEM_LOG_NOIMPL
shortcut macro defined without -DPERL_CORE. Neither codesearch.google.com nor
CPAN::Unpack show any users outside the core. */
#ifdef PERL_CORE
-# define deprecate(s) Perl_ck_warner_d(aTHX_ packWARN(WARN_DEPRECATED), "Use of " s " is deprecated")
+# define deprecate(s) Perl_ck_warner_d(aTHX_ packWARN(WARN_DEPRECATED), \
+ "Use of " s " is deprecated")
#endif
/* Internal macros to deal with gids and uids */
#endif /* HANDY_H */
/*
- * Local variables:
- * c-indentation-style: bsd
- * c-basic-offset: 4
- * indent-tabs-mode: nil
- * End:
- *
* ex: set ts=8 sts=4 sw=4 et:
*/