#include "unicode_constants.h"
/* For to_utf8_fold_flags, q.v. */
-#define FOLD_FLAGS_LOCALE 0x1
-#define FOLD_FLAGS_FULL 0x2
-#define FOLD_FLAGS_NOMIX_ASCII 0x4
+#define FOLD_FLAGS_LOCALE 0x1
+#define FOLD_FLAGS_FULL 0x2
+#define FOLD_FLAGS_NOMIX_ASCII 0x4
/* For _core_swash_init(), internal core use only */
#define _CORE_SWASH_INIT_USER_DEFINED_PROPERTY 0x1
#define _CORE_SWASH_INIT_RETURN_IF_UNDEF 0x2
#define _CORE_SWASH_INIT_ACCEPT_INVLIST 0x4
+/*
+=head1 Unicode Support
+L<perlguts/Unicode Support> has an introduction to this API.
+
+See also L</Character classification>,
+and L</Character case changing>.
+Various functions outside this section also work specially with Unicode.
+Search for the string "utf8" in this document.
+
+=for apidoc is_ascii_string
+
+This is a misleadingly-named synonym for L</is_invariant_string>.
+On ASCII-ish platforms, the name isn't misleading: the ASCII-range characters
+are exactly the UTF-8 invariants. But EBCDIC machines have more invariants
+than just the ASCII characters, so C<is_invariant_string> is preferred.
+
+=cut
+*/
+#define is_ascii_string(s, len) is_invariant_string(s, len)
+
#define uvchr_to_utf8(a,b) uvchr_to_utf8_flags(a,b,0)
#define uvchr_to_utf8_flags(d,uv,flags) \
uvoffuni_to_utf8_flags(d,NATIVE_TO_UNI(uv),flags)
ckWARN_d(WARN_UTF8) ? 0 : UTF8_ALLOW_ANY)
#define to_uni_fold(c, p, lenp) _to_uni_fold_flags(c, p, lenp, FOLD_FLAGS_FULL)
-#define to_utf8_fold(c, p, lenp) _to_utf8_fold_flags(c, p, lenp, \
- FOLD_FLAGS_FULL, NULL)
-#define to_utf8_lower(a,b,c) _to_utf8_lower_flags(a,b,c,0, NULL)
-#define to_utf8_upper(a,b,c) _to_utf8_upper_flags(a,b,c,0, NULL)
-#define to_utf8_title(a,b,c) _to_utf8_title_flags(a,b,c,0, NULL)
+#define to_utf8_fold(c, p, lenp) _to_utf8_fold_flags(c, p, lenp, FOLD_FLAGS_FULL)
+#define to_utf8_lower(a,b,c) _to_utf8_lower_flags(a,b,c,0)
+#define to_utf8_upper(a,b,c) _to_utf8_upper_flags(a,b,c,0)
+#define to_utf8_title(a,b,c) _to_utf8_title_flags(a,b,c,0)
/* Source backward compatibility. */
#define is_utf8_string_loc(s, len, ep) is_utf8_string_loclen(s, len, ep, 0)
#define foldEQ_utf8(s1, pe1, l1, u1, s2, pe2, l2, u2) \
foldEQ_utf8_flags(s1, pe1, l1, u1, s2, pe2, l2, u2, 0)
-#define FOLDEQ_UTF8_NOMIX_ASCII (1 << 0)
-#define FOLDEQ_UTF8_LOCALE (1 << 1)
+#define FOLDEQ_UTF8_NOMIX_ASCII (1 << 0)
+#define FOLDEQ_LOCALE (1 << 1)
#define FOLDEQ_S1_ALREADY_FOLDED (1 << 2)
#define FOLDEQ_S2_ALREADY_FOLDED (1 << 3)
+#define FOLDEQ_S1_FOLDS_SANE (1 << 4)
+#define FOLDEQ_S2_FOLDS_SANE (1 << 5)
-/*
-=for apidoc ibcmp_utf8
-
-This is a synonym for (! foldEQ_utf8())
-
-=cut
-*/
#define ibcmp_utf8(s1, pe1, l1, u1, s2, pe2, l2, u2) \
cBOOL(! foldEQ_utf8(s1, pe1, l1, u1, s2, pe2, l2, u2))
/* 0xA0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* bogus: continuation byte */
/* 0xB0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* bogus: continuation byte */
/* 0xC0 */ 2,2, /* overlong */
-/* 0xC2 */ 2,2,2,2,2,2,2,2,2,2,2,2,2,2, /* U+0080 to U+03FF */
+/* 0xC2 */ 2,2,2,2,2,2,2,2,2,2,2,2,2,2, /* U+0080 to U+03FF */
/* 0xD0 */ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, /* U+0400 to U+07FF */
/* 0xE0 */ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, /* U+0800 to U+FFFF */
/* 0xF0 */ 4,4,4,4,4,4,4,4,5,5,5,5,6,6, /* above BMP to 2**31 - 1 */
/* Native character to/from iso-8859-1. Are the identity functions on ASCII
* platforms */
-#define NATIVE_TO_LATIN1(ch) (ch)
-#define LATIN1_TO_NATIVE(ch) (ch)
+#define NATIVE_TO_LATIN1(ch) (__ASSERT_(FITS_IN_8_BITS(ch)) (ch))
+#define LATIN1_TO_NATIVE(ch) (__ASSERT_(FITS_IN_8_BITS(ch)) (ch))
/* I8 is an intermediate version of UTF-8 used only in UTF-EBCDIC. We thus
* consider it to be identical to UTF-8 on ASCII platforms. Strictly speaking
* because they are 8-bit encodings that serve the same purpose in Perl, and
* rarely do we need to distinguish them. The term "NATIVE_UTF8" applies to
* whichever one is applicable on the current platform */
-#define NATIVE_UTF8_TO_I8(ch) (ch)
-#define I8_TO_NATIVE_UTF8(ch) (ch)
+#define NATIVE_UTF8_TO_I8(ch) (__ASSERT_(FITS_IN_8_BITS(ch)) (ch))
+#define I8_TO_NATIVE_UTF8(ch) (__ASSERT_(FITS_IN_8_BITS(ch)) (ch))
/* Transforms in wide UV chars */
#define UNI_TO_NATIVE(ch) (ch)
*/
-/* Is the representation of the Unicode code point 'c' the same regardless of
+/* Is the representation of the Unicode code point 'cp' the same regardless of
* being encoded in UTF-8 or not? */
-#define UNI_IS_INVARIANT(c) (((UV)c) < 0x80)
+#define OFFUNI_IS_INVARIANT(cp) isASCII(cp)
+
+/* Is the representation of the code point 'cp' the same regardless of
+ * being encoded in UTF-8 or not? 'cp' is native if < 256; Unicode otherwise
+ * */
+#define UVCHR_IS_INVARIANT(cp) OFFUNI_IS_INVARIANT(cp)
-/* Is the UTF8-encoded byte 'c' part of a variant sequence in UTF-8? This is
- * the inverse of UTF8_IS_INVARIANT */
-#define UTF8_IS_CONTINUED(c) (((U8)c) & 0x80)
+/* Misleadingly named: is the UTF8-encoded byte 'c' part of a variant sequence
+ * in UTF-8? This is the inverse of UTF8_IS_INVARIANT */
+#define UTF8_IS_CONTINUED(c) (((U8)c) & 0x80)
/* Is the byte 'c' the first byte of a multi-byte UTF8-8 encoded sequence?
* This doesn't catch invariants (they are single-byte). It also excludes the
* illegal overlong sequences that begin with C0 and C1. */
-#define UTF8_IS_START(c) (((U8)c) >= 0xc2)
+#define UTF8_IS_START(c) (((U8)c) >= 0xc2)
/* Is the byte 'c' part of a multi-byte UTF8-8 encoded sequence, and not the
* first byte thereof? */
-#define UTF8_IS_CONTINUATION(c) ((((U8)c) & 0xC0) == 0x80)
+#define UTF8_IS_CONTINUATION(c) ((((U8)c) & 0xC0) == 0x80)
/* Is the UTF8-encoded byte 'c' the first byte of a two byte sequence? Use
* UTF8_IS_NEXT_CHAR_DOWNGRADEABLE() instead if the input isn't known to
/* Is the UTF8-encoded byte 'c' the first byte of a sequence of bytes that
* represent a code point > 255? */
-#define UTF8_IS_ABOVE_LATIN1(c) ((U8)(c) >= 0xc4)
+#define UTF8_IS_ABOVE_LATIN1(c) ((U8)(c) >= 0xc4)
/* This defines the 1-bits that are to be in the first byte of a multi-byte
* UTF-8 encoded character that give the number of bytes that comprise the
#error UTF8_MAXBYTES must be at least 12
#endif
+/* ^? is defined to be DEL on ASCII systems. See the definition of toCTRL()
+ * for more */
+#define QUESTION_MARK_CTRL DEL_NATIVE
+
#define MAX_UTF8_TWO_BYTE 0x7FF
#define UTF8_MAXBYTES_CASE UTF8_MAXBYTES
+/*
+
+=for apidoc Am|STRLEN|UVCHR_SKIP|UV cp
+returns the number of bytes required to represent the code point C<cp> when
+encoded as UTF-8. C<cp> is a native (ASCII or EBCDIC) code point if less than
+255; a Unicode code point otherwise.
+
+=cut
+ */
+#define UVCHR_SKIP(uv) OFFUNISKIP(uv)
+
+/* Surrogates, non-character code points and above-Unicode code points are
+ * problematic in some contexts. This allows code that needs to check for
+ * those to to quickly exclude the vast majority of code points it will
+ * encounter */
+#define isUTF8_POSSIBLY_PROBLEMATIC(c) ((U8) c >= 0xED)
+
#endif /* EBCDIC vs ASCII */
/* Rest of these are attributes of Unicode and perl's internals rather than the
&& UTF8_IS_CONTINUATION(*((s)+1)))
/* Number of bytes a code point occupies in UTF-8. */
-#define NATIVE_SKIP(uv) OFFUNISKIP(NATIVE_TO_UNI(uv))
+#define NATIVE_SKIP(uv) UVCHR_SKIP(uv)
/* Most code which says UNISKIP is really thinking in terms of native code
* points (0-255) plus all those beyond. This is an imprecise term, but having
- * it means existing code continues to work. For precision, use NATIVE_SKIP
- * and OFFUNISKIP */
-#define UNISKIP(uv) NATIVE_SKIP(uv)
+ * it means existing code continues to work. For precision, use UVCHR_SKIP,
+ * NATIVE_SKIP, or OFFUNISKIP */
+#define UNISKIP(uv) UVCHR_SKIP(uv)
+
+/* Longer, but more accurate name */
+#define UTF8_IS_ABOVE_LATIN1_START(c) UTF8_IS_ABOVE_LATIN1(c)
+
+/* Convert a UTF-8 variant Latin1 character to a native code point value.
+ * Needs just one iteration of accumulate. Should be used only if it is known
+ * that the code point is < 256, and is not UTF-8 invariant. Use the slower
+ * but more general TWO_BYTE_UTF8_TO_NATIVE() which handles any code point
+ * representable by two bytes (which turns out to be up through
+ * MAX_PORTABLE_UTF8_TWO_BYTE). The two parameters are:
+ * HI: a downgradable start byte;
+ * LO: continuation.
+ * */
+#define EIGHT_BIT_UTF8_TO_NATIVE(HI, LO) \
+ ( __ASSERT_(UTF8_IS_DOWNGRADEABLE_START(HI)) \
+ __ASSERT_(UTF8_IS_CONTINUATION(LO)) \
+ LATIN1_TO_NATIVE(UTF8_ACCUMULATE(( \
+ NATIVE_UTF8_TO_I8(HI) & UTF_START_MASK(2)), (LO))))
/* Convert a two (not one) byte utf8 character to a native code point value.
* Needs just one iteration of accumulate. Should not be used unless it is
* Note that the result can be larger than 255 if the input character is not
* downgradable */
#define TWO_BYTE_UTF8_TO_NATIVE(HI, LO) \
+ ( __ASSERT_(UTF8SKIP(HI) == 2) \
+ __ASSERT_(UTF8_IS_CONTINUATION(LO)) \
UNI_TO_NATIVE(UTF8_ACCUMULATE((NATIVE_UTF8_TO_I8(HI) & UTF_START_MASK(2)), \
- (LO)))
+ (LO))))
/* Should never be used, and be deprecated */
#define TWO_BYTE_UTF8_TO_UNI(HI, LO) NATIVE_TO_UNI(TWO_BYTE_UTF8_TO_NATIVE(HI, LO))
-/* How many bytes in the UTF-8 encoded character whose first (perhaps only)
- * byte is pointed to by 's' */
-#define UTF8SKIP(s) PL_utf8skip[*(const U8*)(s)]
+/*
+
+=for apidoc Am|STRLEN|UTF8SKIP|char* s
+returns the number of bytes in the UTF-8 encoded character whose first (perhaps
+only) byte is pointed to by C<s>.
+
+=cut
+ */
+#define UTF8SKIP(s) PL_utf8skip[*(const U8*)(s)]
+#define UTF8_SKIP(s) UTF8SKIP(s)
+
+/* Most code that says 'UNI_' really means the native value for code points up
+ * through 255 */
+#define UNI_IS_INVARIANT(cp) UVCHR_IS_INVARIANT(cp)
/* Is the byte 'c' the same character when encoded in UTF-8 as when not. This
* works on both UTF-8 encoded strings and non-encoded, as it returns TRUE in
- * each for the exact same set of bit patterns. (And it works on any byte in a
- * UTF-8 encoded string) */
-#define UTF8_IS_INVARIANT(c) UNI_IS_INVARIANT(NATIVE_UTF8_TO_I8(c))
+ * each for the exact same set of bit patterns. It is valid on a subset of
+ * what UVCHR_IS_INVARIANT is valid on, so can just use that; and the compiler
+ * should optimize out anything extraneous given the implementation of the
+ * latter */
+#define UTF8_IS_INVARIANT(c) UVCHR_IS_INVARIANT(c)
-/* Like the above, but its name implies a non-UTF8 input, and is implemented
- * differently (for no particular reason) */
-#define NATIVE_BYTE_IS_INVARIANT(c) UNI_IS_INVARIANT(NATIVE_TO_LATIN1(c))
-
-/* Like the above, but accepts any UV as input */
-#define UVCHR_IS_INVARIANT(uv) UNI_IS_INVARIANT(NATIVE_TO_UNI(uv))
+/* Like the above, but its name implies a non-UTF8 input, which as the comments
+ * above show, doesn't matter as to its implementation */
+#define NATIVE_BYTE_IS_INVARIANT(c) UVCHR_IS_INVARIANT(c)
#define MAX_PORTABLE_UTF8_TWO_BYTE 0x3FF /* constrained by EBCDIC */
/* These two are helper macros for the other three sets, and should not be used
* directly anywhere else. 'translate_function' is either NATIVE_TO_LATIN1
- * (which works for code points up to 0xFF) or NATIVE_TO_UNI which works for any
- * code point */
+ * (which works for code points up through 0xFF) or NATIVE_TO_UNI which works
+ * for any code point */
#define __BASE_TWO_BYTE_HI(c, translate_function) \
I8_TO_NATIVE_UTF8((translate_function(c) >> UTF_ACCUMULATION_SHIFT) \
| UTF_START_MARK(2))
I8_TO_NATIVE_UTF8((translate_function(c) & UTF_CONTINUATION_MASK) \
| UTF_CONTINUATION_MARK)
-/* This is another helper macro to avoid preprocessor issues, expanding to an
- * assert followed by a comma under DEBUGGING (hence the comma operator). If
- * we didn't do this, we would get a comma with nothing before it when not
- * DEBUGGING */
-#ifdef DEBUGGING
-# define __ASSERT_(statement) assert(statement),
-#else
-# define __ASSERT_(statement)
-#endif
-
/* The next two macros should not be used. They were designed to be usable as
* the case label of a switch statement, but this doesn't work for EBCDIC. Use
* regen/unicode_constants.pl instead */
* code point whose UTF-8 is known to occupy 2 bytes; they are less efficient
* than the EIGHT_BIT versions on EBCDIC platforms. We use the logical '~'
* operator instead of "<=" to avoid getting compiler warnings.
- * MAX_PORTABLE_UTF8_TWO_BYTE should be exactly all one bits in the lower few
+ * MAX_UTF8_TWO_BYTE should be exactly all one bits in the lower few
* places, so the ~ works */
#define UTF8_TWO_BYTE_HI(c) \
(__ASSERT_((sizeof(c) == 1) \
- || !(((WIDEST_UTYPE)(c)) & ~MAX_PORTABLE_UTF8_TWO_BYTE)) \
- ((U8) __BASE_TWO_BYTE_HI(c, NATIVE_TO_LATIN1)))
+ || !(((WIDEST_UTYPE)(c)) & ~MAX_UTF8_TWO_BYTE)) \
+ ((U8) __BASE_TWO_BYTE_HI(c, NATIVE_TO_UNI)))
#define UTF8_TWO_BYTE_LO(c) \
(__ASSERT_((sizeof(c) == 1) \
- || !(((WIDEST_UTYPE)(c)) & ~MAX_PORTABLE_UTF8_TWO_BYTE)) \
- ((U8) __BASE_TWO_BYTE_LO(c, NATIVE_TO_LATIN1)))
+ || !(((WIDEST_UTYPE)(c)) & ~MAX_UTF8_TWO_BYTE)) \
+ ((U8) __BASE_TWO_BYTE_LO(c, NATIVE_TO_UNI)))
/* This is illegal in any well-formed UTF-8 in both EBCDIC and ASCII
* as it is only in overlongs. */
#define UTF8_MAX_FOLD_CHAR_EXPAND 3
#define IN_BYTES (CopHINTS_get(PL_curcop) & HINT_BYTES)
+
+/*
+
+=for apidoc Am|bool|DO_UTF8|SV* sv
+Returns a bool giving whether or not the PV in C<sv> is to be treated as being
+encoded in UTF-8.
+
+You should use this I<after> a call to C<SvPV()> or one of its variants, in
+case any call to string overloading updates the internal UTF-8 encoding flag.
+
+=cut
+*/
#define DO_UTF8(sv) (SvUTF8(sv) && !IN_BYTES)
-#define IN_UNI_8_BIT \
- (CopHINTS_get(PL_curcop) & (HINT_UNI_8_BIT|HINT_LOCALE_NOT_CHARS) \
- && ! IN_LOCALE_RUNTIME && ! IN_BYTES)
+
+/* Should all strings be treated as Unicode, and not just UTF-8 encoded ones?
+ * Is so within 'feature unicode_strings' or 'locale :not_characters', and not
+ * within 'use bytes'. UTF-8 locales are not tested for here, but perhaps
+ * could be */
+#define IN_UNI_8_BIT \
+ (((CopHINTS_get(PL_curcop) & (HINT_UNI_8_BIT)) \
+ || (CopHINTS_get(PL_curcop) & HINT_LOCALE_PARTIAL \
+ /* -1 below is for :not_characters */ \
+ && _is_in_locale_category(FALSE, -1))) \
+ && ! IN_BYTES)
#define UTF8_ALLOW_EMPTY 0x0001 /* Allow a zero length string */
#define UTF8_WARN_SUPER 0x0400 /* points above the legal max */
/* Code points which never were part of the original UTF-8 standard, the first
- * byte of which is a FE or FF on ASCII platforms. */
+ * byte of which is a FE or FF on ASCII platforms. If the first byte is FF, it
+ * will overflow a 32-bit word. If the first byte is FE, it will overflow a
+ * signed 32-bit word. */
#define UTF8_DISALLOW_FE_FF 0x0800
#define UTF8_WARN_FE_FF 0x1000
#define UTF8_ALLOW_FFFF 0
#define UTF8_ALLOW_SURROGATE 0
-#define UTF8_DISALLOW_ILLEGAL_INTERCHANGE (UTF8_DISALLOW_SUPER|UTF8_DISALLOW_NONCHAR|UTF8_DISALLOW_SURROGATE|UTF8_DISALLOW_FE_FF)
+#define UTF8_DISALLOW_ILLEGAL_INTERCHANGE \
+ (UTF8_DISALLOW_SUPER|UTF8_DISALLOW_NONCHAR \
+ |UTF8_DISALLOW_SURROGATE|UTF8_DISALLOW_FE_FF)
#define UTF8_WARN_ILLEGAL_INTERCHANGE \
(UTF8_WARN_SUPER|UTF8_WARN_NONCHAR|UTF8_WARN_SURROGATE|UTF8_WARN_FE_FF)
#define UTF8_ALLOW_ANY \
#define UTF8_ALLOW_DEFAULT (ckWARN(WARN_UTF8) ? 0 : \
UTF8_ALLOW_ANYUV)
-/* Surrogates, non-character code points and above-Unicode code points are
- * problematic in some contexts. This allows code that needs to check for
- * those to to quickly exclude the vast majority of code points it will
- * encounter */
-#define UTF8_FIRST_PROBLEMATIC_CODE_POINT_FIRST_BYTE \
- FIRST_SURROGATE_UTF8_FIRST_BYTE
+/* Several of the macros below have a second parameter that is currently
+ * unused; but could be used in the future to make sure that the input is
+ * well-formed. */
-#define UTF8_IS_SURROGATE(s) cBOOL(is_SURROGATE_utf8(s))
+#define UTF8_IS_SURROGATE(s, e) cBOOL(is_SURROGATE_utf8(s))
#define UTF8_IS_REPLACEMENT(s, send) cBOOL(is_REPLACEMENT_utf8_safe(s,send))
/* ASCII EBCDIC I8
* U+10FFFF: \xF4\x8F\xBF\xBF \xF9\xA1\xBF\xBF\xBF max legal Unicode
* U+110000: \xF4\x90\x80\x80 \xF9\xA2\xA0\xA0\xA0
* U+110001: \xF4\x90\x80\x81 \xF9\xA2\xA0\xA0\xA1
- */
+ *
+ * BE AWARE that this test doesn't rule out malformed code points, in
+ * particular overlongs */
#ifdef EBCDIC /* Both versions assume well-formed UTF8 */
-# define UTF8_IS_SUPER(s) (NATIVE_UTF8_TO_I8(* (U8*) (s)) >= 0xF9 \
+# define UTF8_IS_SUPER(s, e) (NATIVE_UTF8_TO_I8(* (U8*) (s)) >= 0xF9 \
&& (NATIVE_UTF8_TO_I8(* (U8*) (s)) > 0xF9 \
|| (NATIVE_UTF8_TO_I8(* ((U8*) (s) + 1)) >= 0xA2)))
#else
-# define UTF8_IS_SUPER(s) (*(U8*) (s) >= 0xF4 \
- && (*(U8*) (s) > 0xF4 || (*((U8*) (s) + 1) >= 0x90)))
+# define UTF8_IS_SUPER(s, e) (*(U8*) (s) >= 0xF4 \
+ && (*(U8*) (s) > 0xF4 || (*((U8*) (s) + 1) >= 0x90)))
#endif
/* These are now machine generated, and the 'given' clause is no longer
* applicable */
-#define UTF8_IS_NONCHAR_GIVEN_THAT_NON_SUPER_AND_GE_PROBLEMATIC(s) \
+#define UTF8_IS_NONCHAR_GIVEN_THAT_NON_SUPER_AND_GE_PROBLEMATIC(s, e) \
cBOOL(is_NONCHAR_utf8(s))
-#define UTF8_IS_NONCHAR_(s) \
- UTF8_IS_NONCHAR_GIVEN_THAT_NON_SUPER_AND_GE_PROBLEMATIC(s)
+#define UTF8_IS_NONCHAR(s, e) \
+ UTF8_IS_NONCHAR_GIVEN_THAT_NON_SUPER_AND_GE_PROBLEMATIC(s, e)
#define UNICODE_SURROGATE_FIRST 0xD800
#define UNICODE_SURROGATE_LAST 0xDFFF
#define GREEK_CAPITAL_LETTER_MU 0x039C /* Upper and title case
of MICRON */
#define LATIN_CAPITAL_LETTER_Y_WITH_DIAERESIS 0x0178 /* Also is title case */
-#define LATIN_CAPITAL_LETTER_SHARP_S 0x1E9E
+#ifdef LATIN_CAPITAL_LETTER_SHARP_S_UTF8
+# define LATIN_CAPITAL_LETTER_SHARP_S 0x1E9E
+#endif
+#define LATIN_CAPITAL_LETTER_I_WITH_DOT_ABOVE 0x130
+#define LATIN_SMALL_LETTER_DOTLESS_I 0x131
#define LATIN_SMALL_LETTER_LONG_S 0x017F
#define LATIN_SMALL_LIGATURE_LONG_S_T 0xFB05
#define LATIN_SMALL_LIGATURE_ST 0xFB06
(ANYOF_NONBITMAP(node)) && \
(ANYOF_FLAGS(node) & ANYOF_LOC_NONBITMAP_FOLD) && \
((end) > (input) + 1) && \
- toFOLD((input)[0]) == 's' && \
- toFOLD((input)[1]) == 's')
+ isALPHA_FOLD_EQ((input)[0], 's'))
+
#define SHARP_S_SKIP 2
/* If you want to exclude surrogates, and beyond legal Unicode, see the blame
* log for earlier versions which gave details for these */
+/* A helper macro for isUTF8_CHAR, so use that one, and not this one. This is
+ * retained solely for backwards compatibility and may be deprecated and
+ * removed in a future Perl version.
+ *
+ * regen/regcharclass.pl generates is_UTF8_CHAR_utf8() macros for up to these
+ * number of bytes. So this has to be coordinated with that file */
+#ifdef EBCDIC
+# define IS_UTF8_CHAR_FAST(n) ((n) <= 3)
+#else
+# define IS_UTF8_CHAR_FAST(n) ((n) <= 4)
+#endif
+
#ifndef EBCDIC
-/* This was generated by regen/regcharclass.pl, and then moved here. The lines
- * that generated it were then commented out. This was done solely because it
- * takes on the order of 10 minutes to generate, and is never going to change.
- * The EBCDIC equivalent hasn't been commented out in regcharclass.pl, so it
- * should generate and run the correct stuff */
+/* A helper macro for isUTF8_CHAR, so use that one instead of this. This was
+ * generated by regen/regcharclass.pl, and then moved here. The lines that
+ * generated it were then commented out. This was done solely because it takes
+ * on the order of 10 minutes to generate, and is never going to change, unless
+ * the generated code is improved.
+ *
+ * The EBCDIC versions have been cut to not cover all of legal Unicode,
+ * otherwise they take too long to generate; besides there is a separate one
+ * for each code page, so they are in regcharclass.h instead of here */
/*
- UTF8_CHAR: Matches utf8 from 1 to 4 bytes
+ UTF8_CHAR: Matches legal UTF-8 encoded characters from 2 through 4 bytes
- 0x0 - 0x1FFFFF
+ 0x80 - 0x1FFFFF
*/
/*** GENERATED CODE ***/
-#define is_UTF8_CHAR_utf8_safe(s,e) \
-( ((e)-(s) > 3) ? \
- ( ( ( ((U8*)s)[0] & 0x80 ) == 0x00 ) ? 1 \
- : ( 0xC2 <= ((U8*)s)[0] && ((U8*)s)[0] <= 0xDF ) ? \
- ( ( ( ((U8*)s)[1] & 0xC0 ) == 0x80 ) ? 2 : 0 ) \
- : ( 0xE0 == ((U8*)s)[0] ) ? \
- ( ( ( ( ((U8*)s)[1] & 0xE0 ) == 0xA0 ) && ( ( ((U8*)s)[2] & 0xC0 ) == 0x80 ) ) ? 3 : 0 )\
- : ( 0xE1 <= ((U8*)s)[0] && ((U8*)s)[0] <= 0xEF ) ? \
- ( ( ( ( ((U8*)s)[1] & 0xC0 ) == 0x80 ) && ( ( ((U8*)s)[2] & 0xC0 ) == 0x80 ) ) ? 3 : 0 )\
- : ( 0xF0 == ((U8*)s)[0] ) ? \
- ( ( ( ( 0x90 <= ((U8*)s)[1] && ((U8*)s)[1] <= 0xBF ) && ( ( ((U8*)s)[2] & 0xC0 ) == 0x80 ) ) && ( ( ((U8*)s)[3] & 0xC0 ) == 0x80 ) ) ? 4 : 0 )\
- : ( ( ( ( 0xF1 <= ((U8*)s)[0] && ((U8*)s)[0] <= 0xF7 ) && ( ( ((U8*)s)[1] & 0xC0 ) == 0x80 ) ) && ( ( ((U8*)s)[2] & 0xC0 ) == 0x80 ) ) && ( ( ((U8*)s)[3] & 0xC0 ) == 0x80 ) ) ? 4 : 0 )\
-: ((e)-(s) > 2) ? \
- ( ( ( ((U8*)s)[0] & 0x80 ) == 0x00 ) ? 1 \
- : ( 0xC2 <= ((U8*)s)[0] && ((U8*)s)[0] <= 0xDF ) ? \
- ( ( ( ((U8*)s)[1] & 0xC0 ) == 0x80 ) ? 2 : 0 ) \
- : ( 0xE0 == ((U8*)s)[0] ) ? \
- ( ( ( ( ((U8*)s)[1] & 0xE0 ) == 0xA0 ) && ( ( ((U8*)s)[2] & 0xC0 ) == 0x80 ) ) ? 3 : 0 )\
- : ( ( ( 0xE1 <= ((U8*)s)[0] && ((U8*)s)[0] <= 0xEF ) && ( ( ((U8*)s)[1] & 0xC0 ) == 0x80 ) ) && ( ( ((U8*)s)[2] & 0xC0 ) == 0x80 ) ) ? 3 : 0 )\
-: ((e)-(s) > 1) ? \
- ( ( ( ((U8*)s)[0] & 0x80 ) == 0x00 ) ? 1 \
- : ( ( 0xC2 <= ((U8*)s)[0] && ((U8*)s)[0] <= 0xDF ) && ( ( ((U8*)s)[1] & 0xC0 ) == 0x80 ) ) ? 2 : 0 )\
-: ((e)-(s) > 0) ? \
- ( ( ((U8*)s)[0] & 0x80 ) == 0x00 ) \
-: 0 )
+#define is_UTF8_CHAR_utf8_no_length_checks(s) \
+( ( 0xC2 <= ((U8*)s)[0] && ((U8*)s)[0] <= 0xDF ) ? \
+ ( ( ( ((U8*)s)[1] & 0xC0 ) == 0x80 ) ? 2 : 0 ) \
+: ( 0xE0 == ((U8*)s)[0] ) ? \
+ ( ( ( ( ((U8*)s)[1] & 0xE0 ) == 0xA0 ) && ( ( ((U8*)s)[2] & 0xC0 ) == 0x80 ) ) ? 3 : 0 )\
+: ( 0xE1 <= ((U8*)s)[0] && ((U8*)s)[0] <= 0xEF ) ? \
+ ( ( ( ( ((U8*)s)[1] & 0xC0 ) == 0x80 ) && ( ( ((U8*)s)[2] & 0xC0 ) == 0x80 ) ) ? 3 : 0 )\
+: ( 0xF0 == ((U8*)s)[0] ) ? \
+ ( ( ( ( 0x90 <= ((U8*)s)[1] && ((U8*)s)[1] <= 0xBF ) && ( ( ((U8*)s)[2] & 0xC0 ) == 0x80 ) ) && ( ( ((U8*)s)[3] & 0xC0 ) == 0x80 ) ) ? 4 : 0 )\
+: ( ( ( ( 0xF1 <= ((U8*)s)[0] && ((U8*)s)[0] <= 0xF7 ) && ( ( ((U8*)s)[1] & 0xC0 ) == 0x80 ) ) && ( ( ((U8*)s)[2] & 0xC0 ) == 0x80 ) ) && ( ( ((U8*)s)[3] & 0xC0 ) == 0x80 ) ) ? 4 : 0 )
#endif
-/* IS_UTF8_CHAR(p) is strictly speaking wrong (not UTF-8) because it
- * (1) allows UTF-8 encoded UTF-16 surrogates
- * (2) it allows code points past U+10FFFF.
- * The Perl_is_utf8_char() full "slow" code will handle the Perl
- * "extended UTF-8". */
-#define IS_UTF8_CHAR(p, n) (is_UTF8_CHAR_utf8_safe(p, (p) + (n)) == n)
+/*
-/* regen/regcharclass.pl generates is_UTF8_CHAR_utf8_safe() macros for up to
- * these number of bytes. So this has to be coordinated with it */
-#ifdef EBCDIC
-# define IS_UTF8_CHAR_FAST(n) ((n) <= 5)
-#else
-# define IS_UTF8_CHAR_FAST(n) ((n) <= 4)
-#endif
+=for apidoc Am|STRLEN|isUTF8_CHAR|const U8 *s|const U8 *e
+
+Returns the number of bytes beginning at C<s> which form a legal UTF-8 (or
+UTF-EBCDIC) encoded character, looking no further than S<C<e - s>> bytes into
+C<s>. Returns 0 if the sequence starting at C<s> through S<C<e - 1>> is not
+well-formed UTF-8.
+
+Note that an INVARIANT character (i.e. ASCII on non-EBCDIC
+machines) is a valid UTF-8 character.
+
+=cut
+*/
+
+#define isUTF8_CHAR(s, e) (UNLIKELY((e) <= (s)) \
+ ? 0 \
+ : (UTF8_IS_INVARIANT(*s)) \
+ ? 1 \
+ : UNLIKELY(((e) - (s)) < UTF8SKIP(s)) \
+ ? 0 \
+ : LIKELY(IS_UTF8_CHAR_FAST(UTF8SKIP(s))) \
+ ? is_UTF8_CHAR_utf8_no_length_checks(s) \
+ : _is_utf8_char_slow(s, e))
+
+#define is_utf8_char_buf(buf, buf_end) isUTF8_CHAR(buf, buf_end)
+
+/* Do not use; should be deprecated. Use isUTF8_CHAR() instead; this is
+ * retained solely for backwards compatibility */
+#define IS_UTF8_CHAR(p, n) (isUTF8_CHAR(p, (p) + (n)) == n)
#endif /* H_UTF8 */
/*
- * Local variables:
- * c-indentation-style: bsd
- * c-basic-offset: 4
- * indent-tabs-mode: nil
- * End:
- *
* ex: set ts=8 sts=4 sw=4 et:
*/