X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=utf8.h;h=5ffee5bc510691a915546333fc93a06c655f3bc5;hb=d279ab826c469db5d93d3d728fdcf1acd9265665;hp=a8d440d3bfc57869c7440d4725f130763d10d390;hpb=e1ec3a884f8d8c64eb7e391b2a363f47cbeed570;p=p5sagit%2Fp5-mst-13.2.git diff --git a/utf8.h b/utf8.h index a8d440d..5ffee5b 100644 --- a/utf8.h +++ b/utf8.h @@ -1,6 +1,6 @@ /* utf8.h * - * Copyright (C) 2000, 2001, 2002, by Larry Wall and others + * Copyright (C) 2000, 2001, 2002, 2005, 2006 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. @@ -16,12 +16,17 @@ # define USE_UTF8_IN_NAMES (PL_hints & HINT_UTF8) #endif +/* Source backward compatibility. */ +#define uvuni_to_utf8(d, uv) uvuni_to_utf8_flags(d, uv, 0) +#define is_utf8_string_loc(s, len, ep) is_utf8_string_loclen(s, len, ep, 0) + #ifdef EBCDIC /* The equivalent of these macros but implementing UTF-EBCDIC are in the following header file: */ #include "utfebcdic.h" + #else START_EXTERN_C @@ -42,7 +47,7 @@ EXTCONST unsigned char PL_utf8skip[]; #endif END_EXTERN_C -#define UTF8SKIP(s) PL_utf8skip[*(const U8*)s] +#define UTF8SKIP(s) PL_utf8skip[*(const U8*)(s)] /* Native character to iso-8859-1 */ #define NATIVE_TO_ASCII(ch) (ch) @@ -58,8 +63,8 @@ END_EXTERN_C #define ASCII_TO_NEED(enc,ch) (ch) /* As there are no translations avoid the function wrapper */ -#define Perl_utf8n_to_uvchr Perl_utf8n_to_uvuni -#define Perl_uvchr_to_utf8 Perl_uvuni_to_utf8 +#define utf8n_to_uvchr utf8n_to_uvuni +#define uvchr_to_utf8 uvuni_to_utf8 /* @@ -145,7 +150,7 @@ encoded character. * Note: we try to be careful never to call the isXXX_utf8() functions * unless we're pretty sure we've seen the beginning of a UTF-8 character * (that is, the two high bits are set). Otherwise we risk loading in the - * heavy-duty SWASHINIT and SWASHGET routines unnecessarily. + * heavy-duty swash_init and swash_fetch routines unnecessarily. */ #define isIDFIRST_lazy_if(p,c) ((IN_BYTES || (!c || (*((const U8*)p) < 0xc0))) \ ? isIDFIRST(*(p)) \ @@ -183,21 +188,23 @@ encoded character. * SpecialCasing.txt. */ #define UTF8_MAXBYTES_CASE 6 -#define IN_BYTES (PL_curcop->op_private & HINT_BYTES) +#define IN_BYTES (CopHINTS_get(PL_curcop) & HINT_BYTES) #define DO_UTF8(sv) (SvUTF8(sv) && !IN_BYTES) #define UTF8_ALLOW_EMPTY 0x0001 #define UTF8_ALLOW_CONTINUATION 0x0002 #define UTF8_ALLOW_NON_CONTINUATION 0x0004 -#define UTF8_ALLOW_FE_FF 0x0008 +#define UTF8_ALLOW_FE_FF 0x0008 /* Allow above 0x7fffFFFF */ #define UTF8_ALLOW_SHORT 0x0010 #define UTF8_ALLOW_SURROGATE 0x0020 -#define UTF8_ALLOW_FFFF 0x0040 /* Allows also FFFE. */ +#define UTF8_ALLOW_FFFF 0x0040 /* Allow UNICODE_ILLEGAL */ #define UTF8_ALLOW_LONG 0x0080 #define UTF8_ALLOW_ANYUV (UTF8_ALLOW_EMPTY|UTF8_ALLOW_FE_FF|\ UTF8_ALLOW_SURROGATE|UTF8_ALLOW_FFFF) #define UTF8_ALLOW_ANY 0x00FF #define UTF8_CHECK_ONLY 0x0200 +#define UTF8_ALLOW_DEFAULT (ckWARN(WARN_UTF8) ? 0 : \ + UTF8_ALLOW_ANYUV) #define UNICODE_SURROGATE_FIRST 0xD800 #define UNICODE_SURROGATE_LAST 0xDFFF @@ -211,8 +218,8 @@ encoded character. #define UNICODE_ALLOW_SURROGATE 0x0001 /* Allow UTF-16 surrogates (EVIL) */ #define UNICODE_ALLOW_FDD0 0x0002 /* Allow the U+FDD0...U+FDEF */ -#define UNICODE_ALLOW_FFFF 0x0004 /* Allow 0xFFF[EF], 0x1FFF[EF], ... */ -#define UNICODE_ALLOW_SUPER 0x0008 /* Allow past 10xFFFF */ +#define UNICODE_ALLOW_FFFF 0x0004 /* Allow U+FFF[EF], U+1FFF[EF], ... */ +#define UNICODE_ALLOW_SUPER 0x0008 /* Allow past 0x10FFFF */ #define UNICODE_ALLOW_ANY 0x000F #define UNICODE_IS_SURROGATE(c) ((c) >= UNICODE_SURROGATE_FIRST && \ @@ -257,3 +264,79 @@ encoded character. toLOWER((input)[1]) == 's') #endif #define SHARP_S_SKIP 2 + +#ifdef EBCDIC +/* IS_UTF8_CHAR() is not ported to EBCDIC */ +#else +#define IS_UTF8_CHAR_1(p) \ + ((p)[0] <= 0x7F) +#define IS_UTF8_CHAR_2(p) \ + ((p)[0] >= 0xC2 && (p)[0] <= 0xDF && \ + (p)[1] >= 0x80 && (p)[1] <= 0xBF) +#define IS_UTF8_CHAR_3a(p) \ + ((p)[0] == 0xE0 && \ + (p)[1] >= 0xA0 && (p)[1] <= 0xBF && \ + (p)[2] >= 0x80 && (p)[2] <= 0xBF) +#define IS_UTF8_CHAR_3b(p) \ + ((p)[0] >= 0xE1 && (p)[0] <= 0xEC && \ + (p)[1] >= 0x80 && (p)[1] <= 0xBF && \ + (p)[2] >= 0x80 && (p)[2] <= 0xBF) +#define IS_UTF8_CHAR_3c(p) \ + ((p)[0] == 0xED && \ + (p)[1] >= 0x80 && (p)[1] <= 0xBF && \ + (p)[2] >= 0x80 && (p)[2] <= 0xBF) +/* In IS_UTF8_CHAR_3c(p) one could use + * (p)[1] >= 0x80 && (p)[1] <= 0x9F + * if one wanted to exclude surrogates. */ +#define IS_UTF8_CHAR_3d(p) \ + ((p)[0] >= 0xEE && (p)[0] <= 0xEF && \ + (p)[1] >= 0x80 && (p)[1] <= 0xBF && \ + (p)[2] >= 0x80 && (p)[2] <= 0xBF) +#define IS_UTF8_CHAR_4a(p) \ + ((p)[0] == 0xF0 && \ + (p)[1] >= 0x90 && (p)[1] <= 0xBF && \ + (p)[2] >= 0x80 && (p)[2] <= 0xBF && \ + (p)[3] >= 0x80 && (p)[3] <= 0xBF) +#define IS_UTF8_CHAR_4b(p) \ + ((p)[0] >= 0xF1 && (p)[0] <= 0xF3 && \ + (p)[1] >= 0x80 && (p)[1] <= 0xBF && \ + (p)[2] >= 0x80 && (p)[2] <= 0xBF && \ + (p)[3] >= 0x80 && (p)[3] <= 0xBF) +/* In IS_UTF8_CHAR_4c(p) one could use + * (p)[0] == 0xF4 + * if one wanted to stop at the Unicode limit U+10FFFF. + * The 0xF7 allows us to go to 0x1fffff (0x200000 would + * require five bytes). Not doing any further code points + * since that is not needed (and that would not be strict + * UTF-8, anyway). The "slow path" in Perl_is_utf8_char() + * will take care of the "extended UTF-8". */ +#define IS_UTF8_CHAR_4c(p) \ + ((p)[0] == 0xF4 && (p)[0] <= 0xF7 && \ + (p)[1] >= 0x80 && (p)[1] <= 0xBF && \ + (p)[2] >= 0x80 && (p)[2] <= 0xBF && \ + (p)[3] >= 0x80 && (p)[3] <= 0xBF) + +#define IS_UTF8_CHAR_3(p) \ + (IS_UTF8_CHAR_3a(p) || \ + IS_UTF8_CHAR_3b(p) || \ + IS_UTF8_CHAR_3c(p) || \ + IS_UTF8_CHAR_3d(p)) +#define IS_UTF8_CHAR_4(p) \ + (IS_UTF8_CHAR_4a(p) || \ + IS_UTF8_CHAR_4b(p) || \ + IS_UTF8_CHAR_4c(p)) + +/* 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) \ + ((n) == 1 ? IS_UTF8_CHAR_1(p) : \ + (n) == 2 ? IS_UTF8_CHAR_2(p) : \ + (n) == 3 ? IS_UTF8_CHAR_3(p) : \ + (n) == 4 ? IS_UTF8_CHAR_4(p) : 0) + +#define IS_UTF8_CHAR_FAST(n) ((n) <= 4) + +#endif /* IS_UTF8_CHAR() for UTF-8 */