gcc pacifying (RH 7.1/ia64).
[p5sagit/p5-mst-13.2.git] / utf8.c
CommitLineData
a0ed51b3 1/* utf8.c
2 *
bc89e66f 3 * Copyright (c) 1998-2001, Larry Wall
a0ed51b3 4 *
5 * You may distribute under the terms of either the GNU General Public
6 * License or the Artistic License, as specified in the README file.
7 *
8 */
9
10/*
11 * 'What a fix!' said Sam. 'That's the one place in all the lands we've ever
12 * heard of that we don't want to see any closer; and that's the one place
13 * we're trying to get to! And that's just where we can't get, nohow.'
14 *
15 * 'Well do I understand your speech,' he answered in the same language;
16 * 'yet few strangers do so. Why then do you not speak in the Common Tongue,
17 * as is the custom in the West, if you wish to be answered?'
18 *
19 * ...the travellers perceived that the floor was paved with stones of many
20 * hues; branching runes and strange devices intertwined beneath their feet.
21 */
22
23#include "EXTERN.h"
864dbfa3 24#define PERL_IN_UTF8_C
a0ed51b3 25#include "perl.h"
26
27/* Unicode support */
28
eebe1485 29/*
37607a96 30=for apidoc A|U8 *|uvuni_to_utf8|U8 *d|UV uv
eebe1485 31
32Adds the UTF8 representation of the Unicode codepoint C<uv> to the end
33of the string C<d>; C<d> should be have at least C<UTF8_MAXLEN+1> free
34bytes available. The return value is the pointer to the byte after the
9041c2e3 35end of the new character. In other words,
eebe1485 36
9041c2e3 37 d = uvuni_to_utf8(d, uv);
eebe1485 38
39is the recommended Unicode-aware way of saying
40
41 *(d++) = uv;
42
43=cut
44*/
45
dfe13c55 46U8 *
9041c2e3 47Perl_uvuni_to_utf8(pTHX_ U8 *d, UV uv)
a0ed51b3 48{
507b9800 49 if (ckWARN_d(WARN_UTF8)) {
50 if (UNICODE_IS_SURROGATE(uv))
51 Perl_warner(aTHX_ WARN_UTF8, "UTF-16 surrogate 0x%04"UVxf, uv);
52 else if ((uv >= 0xFDD0 && uv <= 0xFDEF) ||
53 (uv == 0xFFFE || uv == 0xFFFF))
54 Perl_warner(aTHX_ WARN_UTF8,
55 "Unicode character 0x%04"UVxf" is illegal", uv);
56 }
c4d5f83a 57 if (UNI_IS_INVARIANT(uv)) {
58 *d++ = UTF_TO_NATIVE(uv);
a0ed51b3 59 return d;
60 }
2d331972 61#if defined(EBCDIC)
1d72bdf6 62 else {
63 STRLEN len = UNISKIP(uv);
64 U8 *p = d+len-1;
65 while (p > d) {
66 *p-- = UTF_TO_NATIVE((uv & UTF_CONTINUATION_MASK) | UTF_CONTINUATION_MARK);
67 uv >>= UTF_ACCUMULATION_SHIFT;
68 }
69 *p = UTF_TO_NATIVE((uv & UTF_START_MASK(len)) | UTF_START_MARK(len));
70 return d+len;
71 }
72#else /* Non loop style */
a0ed51b3 73 if (uv < 0x800) {
74 *d++ = (( uv >> 6) | 0xc0);
75 *d++ = (( uv & 0x3f) | 0x80);
76 return d;
77 }
78 if (uv < 0x10000) {
79 *d++ = (( uv >> 12) | 0xe0);
80 *d++ = (((uv >> 6) & 0x3f) | 0x80);
81 *d++ = (( uv & 0x3f) | 0x80);
82 return d;
83 }
84 if (uv < 0x200000) {
85 *d++ = (( uv >> 18) | 0xf0);
86 *d++ = (((uv >> 12) & 0x3f) | 0x80);
87 *d++ = (((uv >> 6) & 0x3f) | 0x80);
88 *d++ = (( uv & 0x3f) | 0x80);
89 return d;
90 }
91 if (uv < 0x4000000) {
92 *d++ = (( uv >> 24) | 0xf8);
93 *d++ = (((uv >> 18) & 0x3f) | 0x80);
94 *d++ = (((uv >> 12) & 0x3f) | 0x80);
95 *d++ = (((uv >> 6) & 0x3f) | 0x80);
96 *d++ = (( uv & 0x3f) | 0x80);
97 return d;
98 }
99 if (uv < 0x80000000) {
100 *d++ = (( uv >> 30) | 0xfc);
101 *d++ = (((uv >> 24) & 0x3f) | 0x80);
102 *d++ = (((uv >> 18) & 0x3f) | 0x80);
103 *d++ = (((uv >> 12) & 0x3f) | 0x80);
104 *d++ = (((uv >> 6) & 0x3f) | 0x80);
105 *d++ = (( uv & 0x3f) | 0x80);
106 return d;
107 }
6b8eaf93 108#ifdef HAS_QUAD
d7578b48 109 if (uv < UTF8_QUAD_MAX)
a0ed51b3 110#endif
111 {
112 *d++ = 0xfe; /* Can't match U+FEFF! */
113 *d++ = (((uv >> 30) & 0x3f) | 0x80);
114 *d++ = (((uv >> 24) & 0x3f) | 0x80);
115 *d++ = (((uv >> 18) & 0x3f) | 0x80);
116 *d++ = (((uv >> 12) & 0x3f) | 0x80);
117 *d++ = (((uv >> 6) & 0x3f) | 0x80);
118 *d++ = (( uv & 0x3f) | 0x80);
119 return d;
120 }
6b8eaf93 121#ifdef HAS_QUAD
a0ed51b3 122 {
123 *d++ = 0xff; /* Can't match U+FFFE! */
3c77ea2b 124 *d++ = 0x80; /* 6 Reserved bits */
125 *d++ = (((uv >> 60) & 0x0f) | 0x80); /* 2 Reserved bits */
126 *d++ = (((uv >> 54) & 0x3f) | 0x80);
127 *d++ = (((uv >> 48) & 0x3f) | 0x80);
128 *d++ = (((uv >> 42) & 0x3f) | 0x80);
a0ed51b3 129 *d++ = (((uv >> 36) & 0x3f) | 0x80);
130 *d++ = (((uv >> 30) & 0x3f) | 0x80);
131 *d++ = (((uv >> 24) & 0x3f) | 0x80);
132 *d++ = (((uv >> 18) & 0x3f) | 0x80);
133 *d++ = (((uv >> 12) & 0x3f) | 0x80);
134 *d++ = (((uv >> 6) & 0x3f) | 0x80);
135 *d++ = (( uv & 0x3f) | 0x80);
136 return d;
137 }
138#endif
1d72bdf6 139#endif /* Loop style */
a0ed51b3 140}
141
9041c2e3 142
143
144/*
eebe1485 145=for apidoc A|STRLEN|is_utf8_char|U8 *s
146
5da9da9e 147Tests if some arbitrary number of bytes begins in a valid UTF-8
1d72bdf6 148character. Note that an INVARIANT (i.e. ASCII) character is a valid UTF-8 character.
5da9da9e 149The actual number of bytes in the UTF-8 character will be returned if
150it is valid, otherwise 0.
9041c2e3 151
37607a96 152=cut
153*/
067a85ef 154STRLEN
386d01d6 155Perl_is_utf8_char(pTHX_ U8 *s)
156{
157 U8 u = *s;
067a85ef 158 STRLEN slen, len;
159 UV uv, ouv;
386d01d6 160
1d72bdf6 161 if (UTF8_IS_INVARIANT(u))
386d01d6 162 return 1;
163
60006e79 164 if (!UTF8_IS_START(u))
386d01d6 165 return 0;
166
9f07fdcd 167 len = UTF8SKIP(s);
386d01d6 168
60006e79 169 if (len < 2 || !UTF8_IS_CONTINUATION(s[1]))
067a85ef 170 return 0;
171
386d01d6 172 slen = len - 1;
173 s++;
6eb6869e 174 u &= UTF_START_MASK(len);
1d72bdf6 175 uv = u;
067a85ef 176 ouv = uv;
386d01d6 177 while (slen--) {
60006e79 178 if (!UTF8_IS_CONTINUATION(*s))
386d01d6 179 return 0;
8850bf83 180 uv = UTF8_ACCUMULATE(uv, *s);
209a9bc1 181 if (uv < ouv)
067a85ef 182 return 0;
183 ouv = uv;
386d01d6 184 s++;
185 }
067a85ef 186
5bbb0b5a 187 if (UNISKIP(uv) < len)
067a85ef 188 return 0;
189
386d01d6 190 return len;
191}
192
6662521e 193/*
eebe1485 194=for apidoc A|bool|is_utf8_string|U8 *s|STRLEN len
6662521e 195
5da9da9e 196Returns true if first C<len> bytes of the given string form a valid UTF8
197string, false otherwise. Note that 'a valid UTF8 string' does not mean
198'a string that contains UTF8' because a valid ASCII string is a valid
199UTF8 string.
6662521e 200
201=cut
202*/
203
8e84507e 204bool
6662521e 205Perl_is_utf8_string(pTHX_ U8 *s, STRLEN len)
206{
067a85ef 207 U8* x = s;
1aa99e6b 208 U8* send;
067a85ef 209 STRLEN c;
210
1aa99e6b 211 if (!len)
6cd5fe39 212 len = strlen((char *)s);
1aa99e6b 213 send = s + len;
214
6662521e 215 while (x < send) {
216 c = is_utf8_char(x);
067a85ef 217 if (!c)
218 return FALSE;
6662521e 219 x += c;
6662521e 220 }
60006e79 221 if (x != send)
222 return FALSE;
067a85ef 223
224 return TRUE;
6662521e 225}
226
67e989fb 227/*
9041c2e3 228=for apidoc A|UV|utf8n_to_uvuni|U8 *s|STRLEN curlen|STRLEN *retlen|U32 flags
67e989fb 229
9041c2e3 230Bottom level UTF-8 decode routine.
231Returns the unicode code point value of the first character in the string C<s>
ba210ebe 232which is assumed to be in UTF8 encoding and no longer than C<curlen>;
7df053ec 233C<retlen> will be set to the length, in bytes, of that character.
67e989fb 234
235If C<s> does not point to a well-formed UTF8 character, the behaviour
dcad2880 236is dependent on the value of C<flags>: if it contains UTF8_CHECK_ONLY,
237it is assumed that the caller will raise a warning, and this function
28d3d195 238will silently just set C<retlen> to C<-1> and return zero. If the
239C<flags> does not contain UTF8_CHECK_ONLY, warnings about
240malformations will be given, C<retlen> will be set to the expected
241length of the UTF-8 character in bytes, and zero will be returned.
242
243The C<flags> can also contain various flags to allow deviations from
244the strict UTF-8 encoding (see F<utf8.h>).
67e989fb 245
9041c2e3 246Most code should use utf8_to_uvchr() rather than call this directly.
247
37607a96 248=cut
249*/
67e989fb 250
a0ed51b3 251UV
37607a96 252Perl_utf8n_to_uvuni(pTHX_ U8 *s, STRLEN curlen, STRLEN *retlen, U32 flags)
a0ed51b3 253{
097fb8e2 254 U8 *s0 = s;
9c5ffd7c 255 UV uv = *s, ouv = 0;
ba210ebe 256 STRLEN len = 1;
257 bool dowarn = ckWARN_d(WARN_UTF8);
4f849cb6 258 UV startbyte = *s;
ba210ebe 259 STRLEN expectlen = 0;
a0dbb045 260 U32 warning = 0;
261
262/* This list is a superset of the UTF8_ALLOW_XXX. */
263
264#define UTF8_WARN_EMPTY 1
265#define UTF8_WARN_CONTINUATION 2
266#define UTF8_WARN_NON_CONTINUATION 3
267#define UTF8_WARN_FE_FF 4
268#define UTF8_WARN_SHORT 5
269#define UTF8_WARN_OVERFLOW 6
270#define UTF8_WARN_SURROGATE 7
271#define UTF8_WARN_BOM 8
272#define UTF8_WARN_LONG 9
273#define UTF8_WARN_FFFF 10
274
275 if (curlen == 0 &&
276 !(flags & UTF8_ALLOW_EMPTY)) {
277 warning = UTF8_WARN_EMPTY;
0c443dc2 278 goto malformed;
279 }
280
1d72bdf6 281 if (UTF8_IS_INVARIANT(uv)) {
a0ed51b3 282 if (retlen)
283 *retlen = 1;
c4d5f83a 284 return (UV) (NATIVE_TO_UTF(*s));
a0ed51b3 285 }
67e989fb 286
421a8bf2 287 if (UTF8_IS_CONTINUATION(uv) &&
fcc8fcf6 288 !(flags & UTF8_ALLOW_CONTINUATION)) {
a0dbb045 289 warning = UTF8_WARN_CONTINUATION;
ba210ebe 290 goto malformed;
291 }
292
421a8bf2 293 if (UTF8_IS_START(uv) && curlen > 1 && !UTF8_IS_CONTINUATION(s[1]) &&
fcc8fcf6 294 !(flags & UTF8_ALLOW_NON_CONTINUATION)) {
a0dbb045 295 warning = UTF8_WARN_NON_CONTINUATION;
ba210ebe 296 goto malformed;
297 }
9041c2e3 298
1d72bdf6 299#ifdef EBCDIC
75383841 300 uv = NATIVE_TO_UTF(uv);
1d72bdf6 301#else
fcc8fcf6 302 if ((uv == 0xfe || uv == 0xff) &&
303 !(flags & UTF8_ALLOW_FE_FF)) {
a0dbb045 304 warning = UTF8_WARN_FE_FF;
ba210ebe 305 goto malformed;
a0ed51b3 306 }
1d72bdf6 307#endif
308
ba210ebe 309 if (!(uv & 0x20)) { len = 2; uv &= 0x1f; }
310 else if (!(uv & 0x10)) { len = 3; uv &= 0x0f; }
311 else if (!(uv & 0x08)) { len = 4; uv &= 0x07; }
312 else if (!(uv & 0x04)) { len = 5; uv &= 0x03; }
1d72bdf6 313#ifdef EBCDIC
314 else if (!(uv & 0x02)) { len = 6; uv &= 0x01; }
315 else { len = 7; uv &= 0x01; }
316#else
ba210ebe 317 else if (!(uv & 0x02)) { len = 6; uv &= 0x01; }
318 else if (!(uv & 0x01)) { len = 7; uv = 0; }
1d72bdf6 319 else { len = 13; uv = 0; } /* whoa! */
320#endif
321
a0ed51b3 322 if (retlen)
323 *retlen = len;
9041c2e3 324
ba210ebe 325 expectlen = len;
326
fcc8fcf6 327 if ((curlen < expectlen) &&
328 !(flags & UTF8_ALLOW_SHORT)) {
a0dbb045 329 warning = UTF8_WARN_SHORT;
ba210ebe 330 goto malformed;
331 }
332
333 len--;
a0ed51b3 334 s++;
ba210ebe 335 ouv = uv;
336
a0ed51b3 337 while (len--) {
421a8bf2 338 if (!UTF8_IS_CONTINUATION(*s) &&
339 !(flags & UTF8_ALLOW_NON_CONTINUATION)) {
a0dbb045 340 s--;
341 warning = UTF8_WARN_NON_CONTINUATION;
ba210ebe 342 goto malformed;
a0ed51b3 343 }
344 else
8850bf83 345 uv = UTF8_ACCUMULATE(uv, *s);
a0dbb045 346 if (!(uv > ouv)) {
347 /* These cannot be allowed. */
348 if (uv == ouv) {
349 if (!(flags & UTF8_ALLOW_LONG)) {
350 warning = UTF8_WARN_LONG;
351 goto malformed;
352 }
353 }
354 else { /* uv < ouv */
355 /* This cannot be allowed. */
356 warning = UTF8_WARN_OVERFLOW;
357 goto malformed;
358 }
ba210ebe 359 }
360 s++;
361 ouv = uv;
362 }
363
421a8bf2 364 if (UNICODE_IS_SURROGATE(uv) &&
fcc8fcf6 365 !(flags & UTF8_ALLOW_SURROGATE)) {
a0dbb045 366 warning = UTF8_WARN_SURROGATE;
ba210ebe 367 goto malformed;
421a8bf2 368 } else if (UNICODE_IS_BYTE_ORDER_MARK(uv) &&
fcc8fcf6 369 !(flags & UTF8_ALLOW_BOM)) {
a0dbb045 370 warning = UTF8_WARN_BOM;
ba210ebe 371 goto malformed;
fcc8fcf6 372 } else if ((expectlen > UNISKIP(uv)) &&
373 !(flags & UTF8_ALLOW_LONG)) {
a0dbb045 374 warning = UTF8_WARN_LONG;
ba210ebe 375 goto malformed;
421a8bf2 376 } else if (UNICODE_IS_ILLEGAL(uv) &&
a9917092 377 !(flags & UTF8_ALLOW_FFFF)) {
a0dbb045 378 warning = UTF8_WARN_FFFF;
a9917092 379 goto malformed;
a0ed51b3 380 }
ba210ebe 381
a0ed51b3 382 return uv;
ba210ebe 383
384malformed:
385
fcc8fcf6 386 if (flags & UTF8_CHECK_ONLY) {
ba210ebe 387 if (retlen)
cc366d4b 388 *retlen = -1;
ba210ebe 389 return 0;
390 }
391
a0dbb045 392 if (dowarn) {
393 SV* sv = sv_2mortal(newSVpv("Malformed UTF-8 character ", 0));
394
395 switch (warning) {
396 case 0: /* Intentionally empty. */ break;
397 case UTF8_WARN_EMPTY:
398 Perl_sv_catpvf(aTHX_ sv, "(empty string)");
399 break;
400 case UTF8_WARN_CONTINUATION:
097fb8e2 401 Perl_sv_catpvf(aTHX_ sv, "(unexpected continuation byte 0x%02"UVxf", with no preceding start byte)", uv);
a0dbb045 402 break;
403 case UTF8_WARN_NON_CONTINUATION:
097fb8e2 404 if (s == s0)
405 Perl_sv_catpvf(aTHX_ sv, "(unexpected non-continuation byte 0x%02"UVxf", immediately after start byte 0x%02"UVxf")",
406 (UV)s[1], startbyte);
407 else
408 Perl_sv_catpvf(aTHX_ sv, "(unexpected non-continuation byte 0x%02"UVxf", %d byte%s after start byte 0x%02"UVxf", expected %d bytes)",
409 (UV)s[1], s - s0, s - s0 > 1 ? "s" : "", startbyte, expectlen);
410
a0dbb045 411 break;
412 case UTF8_WARN_FE_FF:
413 Perl_sv_catpvf(aTHX_ sv, "(byte 0x%02"UVxf")", uv);
414 break;
415 case UTF8_WARN_SHORT:
097fb8e2 416 Perl_sv_catpvf(aTHX_ sv, "(%d byte%s, need %d, after start byte 0x%02"UVxf")",
417 curlen, curlen == 1 ? "" : "s", expectlen, startbyte);
b31f83c2 418 expectlen = curlen; /* distance for caller to skip */
a0dbb045 419 break;
420 case UTF8_WARN_OVERFLOW:
097fb8e2 421 Perl_sv_catpvf(aTHX_ sv, "(overflow at 0x%"UVxf", byte 0x%02x, after start byte 0x%02"UVxf")",
422 ouv, *s, startbyte);
a0dbb045 423 break;
424 case UTF8_WARN_SURROGATE:
425 Perl_sv_catpvf(aTHX_ sv, "(UTF-16 surrogate 0x%04"UVxf")", uv);
426 break;
427 case UTF8_WARN_BOM:
428 Perl_sv_catpvf(aTHX_ sv, "(byte order mark 0x%04"UVxf")", uv);
429 break;
430 case UTF8_WARN_LONG:
097fb8e2 431 Perl_sv_catpvf(aTHX_ sv, "(%d byte%s, need %d, after start byte 0x%02"UVxf")",
432 expectlen, expectlen == 1 ? "": "s", UNISKIP(uv), startbyte);
a0dbb045 433 break;
434 case UTF8_WARN_FFFF:
435 Perl_sv_catpvf(aTHX_ sv, "(character 0x%04"UVxf")", uv);
436 break;
437 default:
438 Perl_sv_catpvf(aTHX_ sv, "(unknown reason)");
439 break;
440 }
441
442 if (warning) {
443 char *s = SvPVX(sv);
444
445 if (PL_op)
446 Perl_warner(aTHX_ WARN_UTF8,
53e06cf0 447 "%s in %s", s, OP_DESC(PL_op));
a0dbb045 448 else
449 Perl_warner(aTHX_ WARN_UTF8, "%s", s);
450 }
451 }
452
ba210ebe 453 if (retlen)
28d3d195 454 *retlen = expectlen ? expectlen : len;
ba210ebe 455
28d3d195 456 return 0;
a0ed51b3 457}
458
8e84507e 459/*
37607a96 460=for apidoc A|UV|utf8_to_uvchr|U8 *s|STRLEN *retlen
9041c2e3 461
462Returns the native character value of the first character in the string C<s>
463which is assumed to be in UTF8 encoding; C<retlen> will be set to the
464length, in bytes, of that character.
465
466If C<s> does not point to a well-formed UTF8 character, zero is
467returned and retlen is set, if possible, to -1.
468
469=cut
470*/
471
472UV
37607a96 473Perl_utf8_to_uvchr(pTHX_ U8 *s, STRLEN *retlen)
9041c2e3 474{
475 return Perl_utf8n_to_uvchr(aTHX_ s, UTF8_MAXLEN, retlen, 0);
476}
477
478/*
37607a96 479=for apidoc A|UV|utf8_to_uvuni|U8 *s|STRLEN *retlen
9041c2e3 480
481Returns the Unicode code point of the first character in the string C<s>
482which is assumed to be in UTF8 encoding; C<retlen> will be set to the
483length, in bytes, of that character.
484
485This function should only be used when returned UV is considered
486an index into the Unicode semantic tables (e.g. swashes).
487
ba210ebe 488If C<s> does not point to a well-formed UTF8 character, zero is
489returned and retlen is set, if possible, to -1.
8e84507e 490
491=cut
492*/
493
494UV
37607a96 495Perl_utf8_to_uvuni(pTHX_ U8 *s, STRLEN *retlen)
8e84507e 496{
9041c2e3 497 /* Call the low level routine asking for checks */
498 return Perl_utf8n_to_uvuni(aTHX_ s, UTF8_MAXLEN, retlen, 0);
8e84507e 499}
500
b76347f2 501/*
37607a96 502=for apidoc A|STRLEN|utf8_length|U8 *s|U8 *e
b76347f2 503
504Return the length of the UTF-8 char encoded string C<s> in characters.
02eb7b47 505Stops at C<e> (inclusive). If C<e E<lt> s> or if the scan would end
506up past C<e>, croaks.
b76347f2 507
508=cut
509*/
510
511STRLEN
37607a96 512Perl_utf8_length(pTHX_ U8 *s, U8 *e)
b76347f2 513{
514 STRLEN len = 0;
515
8850bf83 516 /* Note: cannot use UTF8_IS_...() too eagerly here since e.g.
517 * the bitops (especially ~) can create illegal UTF-8.
518 * In other words: in Perl UTF-8 is not just for Unicode. */
519
b76347f2 520 if (e < s)
02eb7b47 521 Perl_croak(aTHX_ "panic: utf8_length: unexpected end");
b76347f2 522 while (s < e) {
02eb7b47 523 U8 t = UTF8SKIP(s);
b76347f2 524
525 if (e - s < t)
0064a8a9 526 Perl_croak(aTHX_ "panic: utf8_length: unaligned end");
b76347f2 527 s += t;
528 len++;
529 }
530
531 return len;
532}
533
b06226ff 534/*
eebe1485 535=for apidoc A|IV|utf8_distance|U8 *a|U8 *b
b06226ff 536
537Returns the number of UTF8 characters between the UTF-8 pointers C<a>
538and C<b>.
539
540WARNING: use only if you *know* that the pointers point inside the
541same UTF-8 buffer.
542
37607a96 543=cut
544*/
a0ed51b3 545
02eb7b47 546IV
864dbfa3 547Perl_utf8_distance(pTHX_ U8 *a, U8 *b)
a0ed51b3 548{
02eb7b47 549 IV off = 0;
550
8850bf83 551 /* Note: cannot use UTF8_IS_...() too eagerly here since e.g.
552 * the bitops (especially ~) can create illegal UTF-8.
553 * In other words: in Perl UTF-8 is not just for Unicode. */
554
a0ed51b3 555 if (a < b) {
556 while (a < b) {
02eb7b47 557 U8 c = UTF8SKIP(a);
558
559 if (b - a < c)
560 Perl_croak(aTHX_ "panic: utf8_distance: unaligned end");
561 a += c;
a0ed51b3 562 off--;
563 }
564 }
565 else {
566 while (b < a) {
02eb7b47 567 U8 c = UTF8SKIP(b);
568
569 if (a - b < c)
570 Perl_croak(aTHX_ "panic: utf8_distance: unaligned end");
571 b += c;
a0ed51b3 572 off++;
573 }
574 }
02eb7b47 575
a0ed51b3 576 return off;
577}
578
b06226ff 579/*
37607a96 580=for apidoc A|U8 *|utf8_hop|U8 *s|I32 off
b06226ff 581
8850bf83 582Return the UTF-8 pointer C<s> displaced by C<off> characters, either
583forward or backward.
b06226ff 584
585WARNING: do not use the following unless you *know* C<off> is within
8850bf83 586the UTF-8 data pointed to by C<s> *and* that on entry C<s> is aligned
587on the first byte of character or just after the last byte of a character.
b06226ff 588
37607a96 589=cut
590*/
a0ed51b3 591
592U8 *
864dbfa3 593Perl_utf8_hop(pTHX_ U8 *s, I32 off)
a0ed51b3 594{
8850bf83 595 /* Note: cannot use UTF8_IS_...() too eagerly here since e.g
596 * the bitops (especially ~) can create illegal UTF-8.
597 * In other words: in Perl UTF-8 is not just for Unicode. */
598
a0ed51b3 599 if (off >= 0) {
600 while (off--)
601 s += UTF8SKIP(s);
602 }
603 else {
604 while (off++) {
605 s--;
8850bf83 606 while (UTF8_IS_CONTINUATION(*s))
607 s--;
a0ed51b3 608 }
609 }
610 return s;
611}
612
6940069f 613/*
eebe1485 614=for apidoc A|U8 *|utf8_to_bytes|U8 *s|STRLEN *len
6940069f 615
246fae53 616Converts a string C<s> of length C<len> from UTF8 into byte encoding.
617Unlike C<bytes_to_utf8>, this over-writes the original string, and
618updates len to contain the new length.
67e989fb 619Returns zero on failure, setting C<len> to -1.
6940069f 620
621=cut
622*/
623
624U8 *
37607a96 625Perl_utf8_to_bytes(pTHX_ U8 *s, STRLEN *len)
6940069f 626{
6940069f 627 U8 *send;
628 U8 *d;
dcad2880 629 U8 *save = s;
246fae53 630
631 /* ensure valid UTF8 and chars < 256 before updating string */
dcad2880 632 for (send = s + *len; s < send; ) {
633 U8 c = *s++;
634
1d72bdf6 635 if (!UTF8_IS_INVARIANT(c) &&
636 (!UTF8_IS_DOWNGRADEABLE_START(c) || (s >= send)
637 || !(c = *s++) || !UTF8_IS_CONTINUATION(c))) {
dcad2880 638 *len = -1;
639 return 0;
640 }
246fae53 641 }
dcad2880 642
643 d = s = save;
6940069f 644 while (s < send) {
ed646e6e 645 STRLEN ulen;
9041c2e3 646 *d++ = (U8)utf8_to_uvchr(s, &ulen);
ed646e6e 647 s += ulen;
6940069f 648 }
649 *d = '\0';
246fae53 650 *len = d - save;
6940069f 651 return save;
652}
653
654/*
f9a63242 655=for apidoc A|U8 *|bytes_from_utf8|U8 *s|STRLEN *len|bool *is_utf8
656
657Converts a string C<s> of length C<len> from UTF8 into byte encoding.
658Unlike <utf8_to_bytes> but like C<bytes_to_utf8>, returns a pointer to
ef9edfd0 659the newly-created string, and updates C<len> to contain the new
660length. Returns the original string if no conversion occurs, C<len>
661is unchanged. Do nothing if C<is_utf8> points to 0. Sets C<is_utf8> to
6620 if C<s> is converted or contains all 7bit characters.
f9a63242 663
37607a96 664=cut
665*/
f9a63242 666
667U8 *
37607a96 668Perl_bytes_from_utf8(pTHX_ U8 *s, STRLEN *len, bool *is_utf8)
f9a63242 669{
f9a63242 670 U8 *d;
671 U8 *start = s;
db42d148 672 U8 *send;
f9a63242 673 I32 count = 0;
674
675 if (!*is_utf8)
676 return start;
677
ef9edfd0 678 /* ensure valid UTF8 and chars < 256 before converting string */
f9a63242 679 for (send = s + *len; s < send;) {
680 U8 c = *s++;
1d72bdf6 681 if (!UTF8_IS_INVARIANT(c)) {
db42d148 682 if (UTF8_IS_DOWNGRADEABLE_START(c) && s < send &&
683 (c = *s++) && UTF8_IS_CONTINUATION(c))
684 count++;
685 else
f9a63242 686 return start;
db42d148 687 }
f9a63242 688 }
689
690 *is_utf8 = 0;
691
f9a63242 692 Newz(801, d, (*len) - count + 1, U8);
ef9edfd0 693 s = start; start = d;
f9a63242 694 while (s < send) {
695 U8 c = *s++;
c4d5f83a 696 if (!UTF8_IS_INVARIANT(c)) {
697 /* Then it is two-byte encoded */
698 c = UTF8_ACCUMULATE(NATIVE_TO_UTF(c), *s++);
699 c = ASCII_TO_NATIVE(c);
700 }
701 *d++ = c;
f9a63242 702 }
703 *d = '\0';
704 *len = d - start;
705 return start;
706}
707
708/*
eebe1485 709=for apidoc A|U8 *|bytes_to_utf8|U8 *s|STRLEN *len
6940069f 710
711Converts a string C<s> of length C<len> from ASCII into UTF8 encoding.
6662521e 712Returns a pointer to the newly-created string, and sets C<len> to
713reflect the new length.
6940069f 714
497711e7 715=cut
6940069f 716*/
717
718U8*
37607a96 719Perl_bytes_to_utf8(pTHX_ U8 *s, STRLEN *len)
6940069f 720{
6940069f 721 U8 *send;
722 U8 *d;
723 U8 *dst;
6662521e 724 send = s + (*len);
6940069f 725
6662521e 726 Newz(801, d, (*len) * 2 + 1, U8);
6940069f 727 dst = d;
728
729 while (s < send) {
db42d148 730 UV uv = NATIVE_TO_ASCII(*s++);
c4d5f83a 731 if (UNI_IS_INVARIANT(uv))
732 *d++ = UTF_TO_NATIVE(uv);
6940069f 733 else {
90f44359 734 *d++ = UTF8_EIGHT_BIT_HI(uv);
735 *d++ = UTF8_EIGHT_BIT_LO(uv);
6940069f 736 }
737 }
738 *d = '\0';
6662521e 739 *len = d-dst;
6940069f 740 return dst;
741}
742
a0ed51b3 743/*
dea0fc0b 744 * Convert native (big-endian) or reversed (little-endian) UTF-16 to UTF-8.
a0ed51b3 745 *
746 * Destination must be pre-extended to 3/2 source. Do not use in-place.
747 * We optimize for native, for obvious reasons. */
748
749U8*
dea0fc0b 750Perl_utf16_to_utf8(pTHX_ U8* p, U8* d, I32 bytelen, I32 *newlen)
a0ed51b3 751{
dea0fc0b 752 U8* pend;
753 U8* dstart = d;
754
755 if (bytelen & 1)
a7867d0a 756 Perl_croak(aTHX_ "panic: utf16_to_utf8: odd bytelen");
dea0fc0b 757
758 pend = p + bytelen;
759
a0ed51b3 760 while (p < pend) {
dea0fc0b 761 UV uv = (p[0] << 8) + p[1]; /* UTF-16BE */
762 p += 2;
a0ed51b3 763 if (uv < 0x80) {
764 *d++ = uv;
765 continue;
766 }
767 if (uv < 0x800) {
768 *d++ = (( uv >> 6) | 0xc0);
769 *d++ = (( uv & 0x3f) | 0x80);
770 continue;
771 }
772 if (uv >= 0xd800 && uv < 0xdbff) { /* surrogates */
dea0fc0b 773 UV low = *p++;
774 if (low < 0xdc00 || low >= 0xdfff)
775 Perl_croak(aTHX_ "Malformed UTF-16 surrogate");
a0ed51b3 776 uv = ((uv - 0xd800) << 10) + (low - 0xdc00) + 0x10000;
777 }
778 if (uv < 0x10000) {
779 *d++ = (( uv >> 12) | 0xe0);
780 *d++ = (((uv >> 6) & 0x3f) | 0x80);
781 *d++ = (( uv & 0x3f) | 0x80);
782 continue;
783 }
784 else {
785 *d++ = (( uv >> 18) | 0xf0);
786 *d++ = (((uv >> 12) & 0x3f) | 0x80);
787 *d++ = (((uv >> 6) & 0x3f) | 0x80);
788 *d++ = (( uv & 0x3f) | 0x80);
789 continue;
790 }
791 }
dea0fc0b 792 *newlen = d - dstart;
a0ed51b3 793 return d;
794}
795
796/* Note: this one is slightly destructive of the source. */
797
798U8*
dea0fc0b 799Perl_utf16_to_utf8_reversed(pTHX_ U8* p, U8* d, I32 bytelen, I32 *newlen)
a0ed51b3 800{
801 U8* s = (U8*)p;
802 U8* send = s + bytelen;
803 while (s < send) {
804 U8 tmp = s[0];
805 s[0] = s[1];
806 s[1] = tmp;
807 s += 2;
808 }
dea0fc0b 809 return utf16_to_utf8(p, d, bytelen, newlen);
a0ed51b3 810}
811
812/* for now these are all defined (inefficiently) in terms of the utf8 versions */
813
814bool
84afefe6 815Perl_is_uni_alnum(pTHX_ UV c)
a0ed51b3 816{
ad391ad9 817 U8 tmpbuf[UTF8_MAXLEN+1];
2b9d42f0 818 uvchr_to_utf8(tmpbuf, (UV)c);
a0ed51b3 819 return is_utf8_alnum(tmpbuf);
820}
821
822bool
84afefe6 823Perl_is_uni_alnumc(pTHX_ UV c)
b8c5462f 824{
ad391ad9 825 U8 tmpbuf[UTF8_MAXLEN+1];
2b9d42f0 826 uvchr_to_utf8(tmpbuf, (UV)c);
b8c5462f 827 return is_utf8_alnumc(tmpbuf);
828}
829
830bool
84afefe6 831Perl_is_uni_idfirst(pTHX_ UV c)
a0ed51b3 832{
ad391ad9 833 U8 tmpbuf[UTF8_MAXLEN+1];
2b9d42f0 834 uvchr_to_utf8(tmpbuf, (UV)c);
a0ed51b3 835 return is_utf8_idfirst(tmpbuf);
836}
837
838bool
84afefe6 839Perl_is_uni_alpha(pTHX_ UV c)
a0ed51b3 840{
ad391ad9 841 U8 tmpbuf[UTF8_MAXLEN+1];
2b9d42f0 842 uvchr_to_utf8(tmpbuf, (UV)c);
a0ed51b3 843 return is_utf8_alpha(tmpbuf);
844}
845
846bool
84afefe6 847Perl_is_uni_ascii(pTHX_ UV c)
4d61ec05 848{
ad391ad9 849 U8 tmpbuf[UTF8_MAXLEN+1];
2b9d42f0 850 uvchr_to_utf8(tmpbuf, (UV)c);
4d61ec05 851 return is_utf8_ascii(tmpbuf);
852}
853
854bool
84afefe6 855Perl_is_uni_space(pTHX_ UV c)
a0ed51b3 856{
ad391ad9 857 U8 tmpbuf[UTF8_MAXLEN+1];
2b9d42f0 858 uvchr_to_utf8(tmpbuf, (UV)c);
a0ed51b3 859 return is_utf8_space(tmpbuf);
860}
861
862bool
84afefe6 863Perl_is_uni_digit(pTHX_ UV c)
a0ed51b3 864{
ad391ad9 865 U8 tmpbuf[UTF8_MAXLEN+1];
2b9d42f0 866 uvchr_to_utf8(tmpbuf, (UV)c);
a0ed51b3 867 return is_utf8_digit(tmpbuf);
868}
869
870bool
84afefe6 871Perl_is_uni_upper(pTHX_ UV c)
a0ed51b3 872{
ad391ad9 873 U8 tmpbuf[UTF8_MAXLEN+1];
2b9d42f0 874 uvchr_to_utf8(tmpbuf, (UV)c);
a0ed51b3 875 return is_utf8_upper(tmpbuf);
876}
877
878bool
84afefe6 879Perl_is_uni_lower(pTHX_ UV c)
a0ed51b3 880{
ad391ad9 881 U8 tmpbuf[UTF8_MAXLEN+1];
2b9d42f0 882 uvchr_to_utf8(tmpbuf, (UV)c);
a0ed51b3 883 return is_utf8_lower(tmpbuf);
884}
885
886bool
84afefe6 887Perl_is_uni_cntrl(pTHX_ UV c)
b8c5462f 888{
ad391ad9 889 U8 tmpbuf[UTF8_MAXLEN+1];
2b9d42f0 890 uvchr_to_utf8(tmpbuf, (UV)c);
b8c5462f 891 return is_utf8_cntrl(tmpbuf);
892}
893
894bool
84afefe6 895Perl_is_uni_graph(pTHX_ UV c)
b8c5462f 896{
ad391ad9 897 U8 tmpbuf[UTF8_MAXLEN+1];
2b9d42f0 898 uvchr_to_utf8(tmpbuf, (UV)c);
b8c5462f 899 return is_utf8_graph(tmpbuf);
900}
901
902bool
84afefe6 903Perl_is_uni_print(pTHX_ UV c)
a0ed51b3 904{
ad391ad9 905 U8 tmpbuf[UTF8_MAXLEN+1];
2b9d42f0 906 uvchr_to_utf8(tmpbuf, (UV)c);
a0ed51b3 907 return is_utf8_print(tmpbuf);
908}
909
b8c5462f 910bool
84afefe6 911Perl_is_uni_punct(pTHX_ UV c)
b8c5462f 912{
ad391ad9 913 U8 tmpbuf[UTF8_MAXLEN+1];
2b9d42f0 914 uvchr_to_utf8(tmpbuf, (UV)c);
b8c5462f 915 return is_utf8_punct(tmpbuf);
916}
917
4d61ec05 918bool
84afefe6 919Perl_is_uni_xdigit(pTHX_ UV c)
4d61ec05 920{
e7ae6809 921 U8 tmpbuf[UTF8_MAXLEN_UCLC+1];
2b9d42f0 922 uvchr_to_utf8(tmpbuf, (UV)c);
4d61ec05 923 return is_utf8_xdigit(tmpbuf);
924}
925
84afefe6 926UV
927Perl_to_uni_upper(pTHX_ UV c, U8* p, STRLEN *lenp)
a0ed51b3 928{
e7ae6809 929 U8 tmpbuf[UTF8_MAXLEN_UCLC+1];
2b9d42f0 930 uvchr_to_utf8(tmpbuf, (UV)c);
a2a2844f 931 return to_utf8_upper(tmpbuf, p, lenp);
a0ed51b3 932}
933
84afefe6 934UV
935Perl_to_uni_title(pTHX_ UV c, U8* p, STRLEN *lenp)
a0ed51b3 936{
e7ae6809 937 U8 tmpbuf[UTF8_MAXLEN_UCLC+1];
2b9d42f0 938 uvchr_to_utf8(tmpbuf, (UV)c);
a2a2844f 939 return to_utf8_title(tmpbuf, p, lenp);
a0ed51b3 940}
941
84afefe6 942UV
943Perl_to_uni_lower(pTHX_ UV c, U8* p, STRLEN *lenp)
a0ed51b3 944{
d90824e8 945 U8 tmpbuf[UTF8_MAXLEN_UCLC+1];
2b9d42f0 946 uvchr_to_utf8(tmpbuf, (UV)c);
a2a2844f 947 return to_utf8_lower(tmpbuf, p, lenp);
a0ed51b3 948}
949
84afefe6 950UV
951Perl_to_uni_fold(pTHX_ UV c, U8* p, STRLEN *lenp)
952{
d90824e8 953 U8 tmpbuf[UTF8_MAXLEN_FOLD+1];
84afefe6 954 uvchr_to_utf8(tmpbuf, (UV)c);
955 return to_utf8_fold(tmpbuf, p, lenp);
956}
957
a0ed51b3 958/* for now these all assume no locale info available for Unicode > 255 */
959
960bool
84afefe6 961Perl_is_uni_alnum_lc(pTHX_ UV c)
a0ed51b3 962{
963 return is_uni_alnum(c); /* XXX no locale support yet */
964}
965
966bool
84afefe6 967Perl_is_uni_alnumc_lc(pTHX_ UV c)
b8c5462f 968{
969 return is_uni_alnumc(c); /* XXX no locale support yet */
970}
971
972bool
84afefe6 973Perl_is_uni_idfirst_lc(pTHX_ UV c)
a0ed51b3 974{
975 return is_uni_idfirst(c); /* XXX no locale support yet */
976}
977
978bool
84afefe6 979Perl_is_uni_alpha_lc(pTHX_ UV c)
a0ed51b3 980{
981 return is_uni_alpha(c); /* XXX no locale support yet */
982}
983
984bool
84afefe6 985Perl_is_uni_ascii_lc(pTHX_ UV c)
4d61ec05 986{
987 return is_uni_ascii(c); /* XXX no locale support yet */
988}
989
990bool
84afefe6 991Perl_is_uni_space_lc(pTHX_ UV c)
a0ed51b3 992{
993 return is_uni_space(c); /* XXX no locale support yet */
994}
995
996bool
84afefe6 997Perl_is_uni_digit_lc(pTHX_ UV c)
a0ed51b3 998{
999 return is_uni_digit(c); /* XXX no locale support yet */
1000}
1001
1002bool
84afefe6 1003Perl_is_uni_upper_lc(pTHX_ UV c)
a0ed51b3 1004{
1005 return is_uni_upper(c); /* XXX no locale support yet */
1006}
1007
1008bool
84afefe6 1009Perl_is_uni_lower_lc(pTHX_ UV c)
a0ed51b3 1010{
1011 return is_uni_lower(c); /* XXX no locale support yet */
1012}
1013
1014bool
84afefe6 1015Perl_is_uni_cntrl_lc(pTHX_ UV c)
b8c5462f 1016{
1017 return is_uni_cntrl(c); /* XXX no locale support yet */
1018}
1019
1020bool
84afefe6 1021Perl_is_uni_graph_lc(pTHX_ UV c)
b8c5462f 1022{
1023 return is_uni_graph(c); /* XXX no locale support yet */
1024}
1025
1026bool
84afefe6 1027Perl_is_uni_print_lc(pTHX_ UV c)
a0ed51b3 1028{
1029 return is_uni_print(c); /* XXX no locale support yet */
1030}
1031
b8c5462f 1032bool
84afefe6 1033Perl_is_uni_punct_lc(pTHX_ UV c)
b8c5462f 1034{
1035 return is_uni_punct(c); /* XXX no locale support yet */
1036}
1037
4d61ec05 1038bool
84afefe6 1039Perl_is_uni_xdigit_lc(pTHX_ UV c)
4d61ec05 1040{
1041 return is_uni_xdigit(c); /* XXX no locale support yet */
1042}
1043
a0ed51b3 1044bool
864dbfa3 1045Perl_is_utf8_alnum(pTHX_ U8 *p)
a0ed51b3 1046{
386d01d6 1047 if (!is_utf8_char(p))
1048 return FALSE;
a0ed51b3 1049 if (!PL_utf8_alnum)
289d4f09 1050 /* NOTE: "IsWord", not "IsAlnum", since Alnum is a true
1051 * descendant of isalnum(3), in other words, it doesn't
1052 * contain the '_'. --jhi */
1053 PL_utf8_alnum = swash_init("utf8", "IsWord", &PL_sv_undef, 0, 0);
3568d838 1054 return swash_fetch(PL_utf8_alnum, p, TRUE);
a0ed51b3 1055/* return *p == '_' || is_utf8_alpha(p) || is_utf8_digit(p); */
1056#ifdef SURPRISINGLY_SLOWER /* probably because alpha is usually true */
1057 if (!PL_utf8_alnum)
1058 PL_utf8_alnum = swash_init("utf8", "",
1059 sv_2mortal(newSVpv("+utf8::IsAlpha\n+utf8::IsDigit\n005F\n",0)), 0, 0);
3568d838 1060 return swash_fetch(PL_utf8_alnum, p, TRUE);
a0ed51b3 1061#endif
1062}
1063
1064bool
b8c5462f 1065Perl_is_utf8_alnumc(pTHX_ U8 *p)
1066{
386d01d6 1067 if (!is_utf8_char(p))
1068 return FALSE;
b8c5462f 1069 if (!PL_utf8_alnum)
1070 PL_utf8_alnum = swash_init("utf8", "IsAlnumC", &PL_sv_undef, 0, 0);
3568d838 1071 return swash_fetch(PL_utf8_alnum, p, TRUE);
b8c5462f 1072/* return is_utf8_alpha(p) || is_utf8_digit(p); */
1073#ifdef SURPRISINGLY_SLOWER /* probably because alpha is usually true */
1074 if (!PL_utf8_alnum)
1075 PL_utf8_alnum = swash_init("utf8", "",
1076 sv_2mortal(newSVpv("+utf8::IsAlpha\n+utf8::IsDigit\n005F\n",0)), 0, 0);
3568d838 1077 return swash_fetch(PL_utf8_alnum, p, TRUE);
b8c5462f 1078#endif
1079}
1080
1081bool
864dbfa3 1082Perl_is_utf8_idfirst(pTHX_ U8 *p)
a0ed51b3 1083{
1084 return *p == '_' || is_utf8_alpha(p);
1085}
1086
1087bool
864dbfa3 1088Perl_is_utf8_alpha(pTHX_ U8 *p)
a0ed51b3 1089{
386d01d6 1090 if (!is_utf8_char(p))
1091 return FALSE;
a0ed51b3 1092 if (!PL_utf8_alpha)
e24b16f9 1093 PL_utf8_alpha = swash_init("utf8", "IsAlpha", &PL_sv_undef, 0, 0);
3568d838 1094 return swash_fetch(PL_utf8_alpha, p, TRUE);
a0ed51b3 1095}
1096
1097bool
b8c5462f 1098Perl_is_utf8_ascii(pTHX_ U8 *p)
1099{
386d01d6 1100 if (!is_utf8_char(p))
1101 return FALSE;
b8c5462f 1102 if (!PL_utf8_ascii)
1103 PL_utf8_ascii = swash_init("utf8", "IsAscii", &PL_sv_undef, 0, 0);
3568d838 1104 return swash_fetch(PL_utf8_ascii, p, TRUE);
b8c5462f 1105}
1106
1107bool
864dbfa3 1108Perl_is_utf8_space(pTHX_ U8 *p)
a0ed51b3 1109{
386d01d6 1110 if (!is_utf8_char(p))
1111 return FALSE;
a0ed51b3 1112 if (!PL_utf8_space)
3bec3564 1113 PL_utf8_space = swash_init("utf8", "IsSpacePerl", &PL_sv_undef, 0, 0);
3568d838 1114 return swash_fetch(PL_utf8_space, p, TRUE);
a0ed51b3 1115}
1116
1117bool
864dbfa3 1118Perl_is_utf8_digit(pTHX_ U8 *p)
a0ed51b3 1119{
386d01d6 1120 if (!is_utf8_char(p))
1121 return FALSE;
a0ed51b3 1122 if (!PL_utf8_digit)
e24b16f9 1123 PL_utf8_digit = swash_init("utf8", "IsDigit", &PL_sv_undef, 0, 0);
3568d838 1124 return swash_fetch(PL_utf8_digit, p, TRUE);
a0ed51b3 1125}
1126
1127bool
864dbfa3 1128Perl_is_utf8_upper(pTHX_ U8 *p)
a0ed51b3 1129{
386d01d6 1130 if (!is_utf8_char(p))
1131 return FALSE;
a0ed51b3 1132 if (!PL_utf8_upper)
e24b16f9 1133 PL_utf8_upper = swash_init("utf8", "IsUpper", &PL_sv_undef, 0, 0);
3568d838 1134 return swash_fetch(PL_utf8_upper, p, TRUE);
a0ed51b3 1135}
1136
1137bool
864dbfa3 1138Perl_is_utf8_lower(pTHX_ U8 *p)
a0ed51b3 1139{
386d01d6 1140 if (!is_utf8_char(p))
1141 return FALSE;
a0ed51b3 1142 if (!PL_utf8_lower)
e24b16f9 1143 PL_utf8_lower = swash_init("utf8", "IsLower", &PL_sv_undef, 0, 0);
3568d838 1144 return swash_fetch(PL_utf8_lower, p, TRUE);
a0ed51b3 1145}
1146
1147bool
b8c5462f 1148Perl_is_utf8_cntrl(pTHX_ U8 *p)
1149{
386d01d6 1150 if (!is_utf8_char(p))
1151 return FALSE;
b8c5462f 1152 if (!PL_utf8_cntrl)
1153 PL_utf8_cntrl = swash_init("utf8", "IsCntrl", &PL_sv_undef, 0, 0);
3568d838 1154 return swash_fetch(PL_utf8_cntrl, p, TRUE);
b8c5462f 1155}
1156
1157bool
1158Perl_is_utf8_graph(pTHX_ U8 *p)
1159{
386d01d6 1160 if (!is_utf8_char(p))
1161 return FALSE;
b8c5462f 1162 if (!PL_utf8_graph)
1163 PL_utf8_graph = swash_init("utf8", "IsGraph", &PL_sv_undef, 0, 0);
3568d838 1164 return swash_fetch(PL_utf8_graph, p, TRUE);
b8c5462f 1165}
1166
1167bool
864dbfa3 1168Perl_is_utf8_print(pTHX_ U8 *p)
a0ed51b3 1169{
386d01d6 1170 if (!is_utf8_char(p))
1171 return FALSE;
a0ed51b3 1172 if (!PL_utf8_print)
e24b16f9 1173 PL_utf8_print = swash_init("utf8", "IsPrint", &PL_sv_undef, 0, 0);
3568d838 1174 return swash_fetch(PL_utf8_print, p, TRUE);
a0ed51b3 1175}
1176
1177bool
b8c5462f 1178Perl_is_utf8_punct(pTHX_ U8 *p)
1179{
386d01d6 1180 if (!is_utf8_char(p))
1181 return FALSE;
b8c5462f 1182 if (!PL_utf8_punct)
1183 PL_utf8_punct = swash_init("utf8", "IsPunct", &PL_sv_undef, 0, 0);
3568d838 1184 return swash_fetch(PL_utf8_punct, p, TRUE);
b8c5462f 1185}
1186
1187bool
1188Perl_is_utf8_xdigit(pTHX_ U8 *p)
1189{
386d01d6 1190 if (!is_utf8_char(p))
1191 return FALSE;
b8c5462f 1192 if (!PL_utf8_xdigit)
1193 PL_utf8_xdigit = swash_init("utf8", "IsXDigit", &PL_sv_undef, 0, 0);
3568d838 1194 return swash_fetch(PL_utf8_xdigit, p, TRUE);
b8c5462f 1195}
1196
1197bool
864dbfa3 1198Perl_is_utf8_mark(pTHX_ U8 *p)
a0ed51b3 1199{
386d01d6 1200 if (!is_utf8_char(p))
1201 return FALSE;
a0ed51b3 1202 if (!PL_utf8_mark)
e24b16f9 1203 PL_utf8_mark = swash_init("utf8", "IsM", &PL_sv_undef, 0, 0);
3568d838 1204 return swash_fetch(PL_utf8_mark, p, TRUE);
a0ed51b3 1205}
1206
6b5c0936 1207/*
1208=for apidoc A|UV|to_utf8_case|U8 *p|U8* ustrp|STRLEN *lenp|SV **swash|char *normal|char *special
1209
1210The "p" contains the pointer to the UTF-8 string encoding
1211the character that is being converted.
1212
1213The "ustrp" is a pointer to the character buffer to put the
1214conversion result to. The "lenp" is a pointer to the length
1215of the result.
1216
1217The "swash" is a pointer to the swash to use.
1218
1219The "normal" is a string like "ToLower" which means the swash
1220$utf8::ToLower, which is stored in lib/unicore/To/Lower.pl,
1221and loaded by SWASHGET, using lib/utf8_heavy.pl.
1222
1223The "special" is a string like "utf8::ToSpecLower", which means
d1be9408 1224the hash %utf8::ToSpecLower, which is stored in the same file,
6b5c0936 1225lib/unicore/To/Lower.pl, and also loaded by SWASHGET. The access
1226to the hash is by Perl_to_utf8_case().
1227
1228=cut
1229 */
1230
2104c8d9 1231UV
983ffd37 1232Perl_to_utf8_case(pTHX_ U8 *p, U8* ustrp, STRLEN *lenp, SV **swashp,char *normal, char *special)
a0ed51b3 1233{
1234 UV uv;
1235
983ffd37 1236 if (!*swashp)
1237 *swashp = swash_init("utf8", normal, &PL_sv_undef, 4, 0);
1238 uv = swash_fetch(*swashp, p, TRUE);
1239 if (uv)
1240 uv = UNI_TO_NATIVE(uv);
1241 else {
1242 HV *hv;
1243 SV *keysv;
1244 HE *he;
1245
1246 uv = utf8_to_uvchr(p, 0);
1247
1248 if ((hv = get_hv(special, FALSE)) &&
6d47b937 1249 (keysv = sv_2mortal(Perl_newSVpvf(aTHX_ "%04"UVXf, uv))) &&
983ffd37 1250 (he = hv_fetch_ent(hv, keysv, FALSE, 0))) {
1251 SV *val = HeVAL(he);
1252 char *s = SvPV(val, *lenp);
1253 U8 c = *(U8*)s;
1254 if (*lenp > 1 || UNI_IS_INVARIANT(c))
1255 Copy(s, ustrp, *lenp, U8);
1256 else {
1257 /* something in the 0x80..0xFF range */
1258 ustrp[0] = UTF8_EIGHT_BIT_HI(c);
1259 ustrp[1] = UTF8_EIGHT_BIT_LO(c);
1260 *lenp = 2;
1261 }
1262 return 0;
1263 }
1264 }
a58d912c 1265 if (lenp)
d90824e8 1266 *lenp = UNISKIP(uv);
a2a2844f 1267 uvuni_to_utf8(ustrp, uv);
1268 return uv;
a0ed51b3 1269}
1270
2104c8d9 1271UV
983ffd37 1272Perl_to_utf8_upper(pTHX_ U8 *p, U8* ustrp, STRLEN *lenp)
a0ed51b3 1273{
983ffd37 1274 return Perl_to_utf8_case(aTHX_ p, ustrp, lenp,
b4e400f9 1275 &PL_utf8_toupper, "ToUpper", "utf8::ToSpecUpper");
983ffd37 1276}
a0ed51b3 1277
983ffd37 1278UV
1279Perl_to_utf8_title(pTHX_ U8 *p, U8* ustrp, STRLEN *lenp)
1280{
1281 return Perl_to_utf8_case(aTHX_ p, ustrp, lenp,
b4e400f9 1282 &PL_utf8_totitle, "ToTitle", "utf8::ToSpecTitle");
a0ed51b3 1283}
1284
2104c8d9 1285UV
a2a2844f 1286Perl_to_utf8_lower(pTHX_ U8 *p, U8* ustrp, STRLEN *lenp)
a0ed51b3 1287{
983ffd37 1288 return Perl_to_utf8_case(aTHX_ p, ustrp, lenp,
b4e400f9 1289 &PL_utf8_tolower, "ToLower", "utf8::ToSpecLower");
1290}
1291
1292UV
1293Perl_to_utf8_fold(pTHX_ U8 *p, U8* ustrp, STRLEN *lenp)
1294{
1295 return Perl_to_utf8_case(aTHX_ p, ustrp, lenp,
1296 &PL_utf8_tofold, "ToFold", "utf8::ToSpecFold");
a0ed51b3 1297}
1298
1299/* a "swash" is a swatch hash */
1300
1301SV*
864dbfa3 1302Perl_swash_init(pTHX_ char* pkg, char* name, SV *listsv, I32 minbits, I32 none)
a0ed51b3 1303{
1304 SV* retval;
bf1fed83 1305 SV* tokenbufsv = sv_2mortal(NEWSV(0,0));
8e84507e 1306 dSP;
1b026014 1307 HV *stash = gv_stashpvn(pkg, strlen(pkg), FALSE);
f8be5cf0 1308 SV* errsv_save;
ce3b816e 1309
1b026014 1310 if (!gv_fetchmeth(stash, "SWASHNEW", 8, -1)) { /* demand load utf8 */
ce3b816e 1311 ENTER;
f8be5cf0 1312 errsv_save = newSVsv(ERRSV);
ce3b816e 1313 Perl_load_module(aTHX_ PERL_LOADMOD_NOIMPORT, newSVpv(pkg,0), Nullsv);
f8be5cf0 1314 if (!SvTRUE(ERRSV))
1315 sv_setsv(ERRSV, errsv_save);
1316 SvREFCNT_dec(errsv_save);
ce3b816e 1317 LEAVE;
1318 }
1319 SPAGAIN;
a0ed51b3 1320 PUSHSTACKi(PERLSI_MAGIC);
1321 PUSHMARK(SP);
1322 EXTEND(SP,5);
1323 PUSHs(sv_2mortal(newSVpvn(pkg, strlen(pkg))));
1324 PUSHs(sv_2mortal(newSVpvn(name, strlen(name))));
1325 PUSHs(listsv);
1326 PUSHs(sv_2mortal(newSViv(minbits)));
1327 PUSHs(sv_2mortal(newSViv(none)));
1328 PUTBACK;
1329 ENTER;
1330 SAVEI32(PL_hints);
1331 PL_hints = 0;
1332 save_re_context();
bf1fed83 1333 if (PL_curcop == &PL_compiling)
1334 /* XXX ought to be handled by lex_start */
1335 sv_setpv(tokenbufsv, PL_tokenbuf);
f8be5cf0 1336 errsv_save = newSVsv(ERRSV);
864dbfa3 1337 if (call_method("SWASHNEW", G_SCALAR))
8e84507e 1338 retval = newSVsv(*PL_stack_sp--);
a0ed51b3 1339 else
e24b16f9 1340 retval = &PL_sv_undef;
f8be5cf0 1341 if (!SvTRUE(ERRSV))
1342 sv_setsv(ERRSV, errsv_save);
1343 SvREFCNT_dec(errsv_save);
a0ed51b3 1344 LEAVE;
1345 POPSTACK;
e24b16f9 1346 if (PL_curcop == &PL_compiling) {
bf1fed83 1347 STRLEN len;
1348 char* pv = SvPV(tokenbufsv, len);
1349
1350 Copy(pv, PL_tokenbuf, len+1, char);
e24b16f9 1351 PL_curcop->op_private = PL_hints;
a0ed51b3 1352 }
1353 if (!SvROK(retval) || SvTYPE(SvRV(retval)) != SVt_PVHV)
cea2e8a9 1354 Perl_croak(aTHX_ "SWASHNEW didn't return an HV ref");
a0ed51b3 1355 return retval;
1356}
1357
035d37be 1358
1359/* This API is wrong for special case conversions since we may need to
1360 * return several Unicode characters for a single Unicode character
1361 * (see lib/unicore/SpecCase.txt) The SWASHGET in lib/utf8_heavy.pl is
1362 * the lower-level routine, and it is similarly broken for returning
1363 * multiple values. --jhi */
a0ed51b3 1364UV
3568d838 1365Perl_swash_fetch(pTHX_ SV *sv, U8 *ptr, bool do_utf8)
a0ed51b3 1366{
1367 HV* hv = (HV*)SvRV(sv);
3568d838 1368 U32 klen;
1369 U32 off;
a0ed51b3 1370 STRLEN slen;
7d85a32c 1371 STRLEN needents;
4ea42e7f 1372 U8 *tmps = NULL;
a0ed51b3 1373 U32 bit;
1374 SV *retval;
3568d838 1375 U8 tmputf8[2];
1376 UV c = NATIVE_TO_ASCII(*ptr);
1377
1378 if (!do_utf8 && !UNI_IS_INVARIANT(c)) {
1379 tmputf8[0] = UTF8_EIGHT_BIT_HI(c);
1380 tmputf8[1] = UTF8_EIGHT_BIT_LO(c);
1381 ptr = tmputf8;
1382 }
1383 /* Given a UTF-X encoded char 0xAA..0xYY,0xZZ
1384 * then the "swatch" is a vec() for al the chars which start
1385 * with 0xAA..0xYY
1386 * So the key in the hash (klen) is length of encoded char -1
1387 */
1388 klen = UTF8SKIP(ptr) - 1;
1389 off = ptr[klen];
a0ed51b3 1390
7d85a32c 1391 if (klen == 0)
1392 {
1393 /* If char in invariant then swatch is for all the invariant chars
1394 * In both UTF-8 and UTF8-MOD that happens to be UTF_CONTINUATION_MARK
1395 */
1396 needents = UTF_CONTINUATION_MARK;
1397 off = NATIVE_TO_UTF(ptr[klen]);
1398 }
1399 else
1400 {
1401 /* If char is encoded then swatch is for the prefix */
1402 needents = (1 << UTF_ACCUMULATION_SHIFT);
1403 off = NATIVE_TO_UTF(ptr[klen]) & UTF_CONTINUATION_MASK;
1404 }
1405
a0ed51b3 1406 /*
1407 * This single-entry cache saves about 1/3 of the utf8 overhead in test
1408 * suite. (That is, only 7-8% overall over just a hash cache. Still,
1409 * it's nothing to sniff at.) Pity we usually come through at least
1410 * two function calls to get here...
1411 *
1412 * NB: this code assumes that swatches are never modified, once generated!
1413 */
1414
3568d838 1415 if (hv == PL_last_swash_hv &&
a0ed51b3 1416 klen == PL_last_swash_klen &&
3568d838 1417 (!klen || memEQ((char *)ptr, (char *)PL_last_swash_key, klen)) )
a0ed51b3 1418 {
1419 tmps = PL_last_swash_tmps;
1420 slen = PL_last_swash_slen;
1421 }
1422 else {
1423 /* Try our second-level swatch cache, kept in a hash. */
dfe13c55 1424 SV** svp = hv_fetch(hv, (char*)ptr, klen, FALSE);
a0ed51b3 1425
1426 /* If not cached, generate it via utf8::SWASHGET */
dfe13c55 1427 if (!svp || !SvPOK(*svp) || !(tmps = (U8*)SvPV(*svp, slen))) {
a0ed51b3 1428 dSP;
2b9d42f0 1429 /* We use utf8n_to_uvuni() as we want an index into
1430 Unicode tables, not a native character number.
1431 */
1432 UV code_point = utf8n_to_uvuni(ptr, UTF8_MAXLEN, NULL, 0);
f8be5cf0 1433 SV *errsv_save;
a0ed51b3 1434 ENTER;
1435 SAVETMPS;
1436 save_re_context();
1437 PUSHSTACKi(PERLSI_MAGIC);
1438 PUSHMARK(SP);
1439 EXTEND(SP,3);
1440 PUSHs((SV*)sv);
ffbc6a93 1441 /* On EBCDIC & ~(0xA0-1) isn't a useful thing to do */
3568d838 1442 PUSHs(sv_2mortal(newSViv((klen) ?
1443 (code_point & ~(needents - 1)) : 0)));
a0ed51b3 1444 PUSHs(sv_2mortal(newSViv(needents)));
1445 PUTBACK;
f8be5cf0 1446 errsv_save = newSVsv(ERRSV);
864dbfa3 1447 if (call_method("SWASHGET", G_SCALAR))
8e84507e 1448 retval = newSVsv(*PL_stack_sp--);
a0ed51b3 1449 else
e24b16f9 1450 retval = &PL_sv_undef;
f8be5cf0 1451 if (!SvTRUE(ERRSV))
1452 sv_setsv(ERRSV, errsv_save);
1453 SvREFCNT_dec(errsv_save);
a0ed51b3 1454 POPSTACK;
1455 FREETMPS;
1456 LEAVE;
e24b16f9 1457 if (PL_curcop == &PL_compiling)
1458 PL_curcop->op_private = PL_hints;
a0ed51b3 1459
dfe13c55 1460 svp = hv_store(hv, (char*)ptr, klen, retval, 0);
a0ed51b3 1461
7d85a32c 1462 if (!svp || !(tmps = (U8*)SvPV(*svp, slen)) || (slen << 3) < needents)
cea2e8a9 1463 Perl_croak(aTHX_ "SWASHGET didn't return result of proper length");
a0ed51b3 1464 }
1465
1466 PL_last_swash_hv = hv;
1467 PL_last_swash_klen = klen;
1468 PL_last_swash_tmps = tmps;
1469 PL_last_swash_slen = slen;
1470 if (klen)
1471 Copy(ptr, PL_last_swash_key, klen, U8);
1472 }
1473
9faf8d75 1474 switch ((int)((slen << 3) / needents)) {
a0ed51b3 1475 case 1:
1476 bit = 1 << (off & 7);
1477 off >>= 3;
1478 return (tmps[off] & bit) != 0;
1479 case 8:
1480 return tmps[off];
1481 case 16:
1482 off <<= 1;
1483 return (tmps[off] << 8) + tmps[off + 1] ;
1484 case 32:
1485 off <<= 2;
1486 return (tmps[off] << 24) + (tmps[off+1] << 16) + (tmps[off+2] << 8) + tmps[off + 3] ;
1487 }
cea2e8a9 1488 Perl_croak(aTHX_ "panic: swash_fetch");
a0ed51b3 1489 return 0;
1490}
2b9d42f0 1491
1492
1493/*
37607a96 1494=for apidoc A|U8 *|uvchr_to_utf8|U8 *d|UV uv
2b9d42f0 1495
1496Adds the UTF8 representation of the Native codepoint C<uv> to the end
1497of the string C<d>; C<d> should be have at least C<UTF8_MAXLEN+1> free
1498bytes available. The return value is the pointer to the byte after the
1499end of the new character. In other words,
1500
1501 d = uvchr_to_utf8(d, uv);
1502
1503is the recommended wide native character-aware way of saying
1504
1505 *(d++) = uv;
1506
1507=cut
1508*/
1509
1510/* On ASCII machines this is normally a macro but we want a
1511 real function in case XS code wants it
1512*/
1513#undef Perl_uvchr_to_utf8
1514U8 *
1515Perl_uvchr_to_utf8(pTHX_ U8 *d, UV uv)
1516{
1517 return Perl_uvuni_to_utf8(aTHX_ d, NATIVE_TO_UNI(uv));
1518}
1519
1520
1521/*
37607a96 1522=for apidoc A|UV|utf8n_to_uvchr|U8 *s|STRLEN curlen|STRLEN *retlen|U32 flags
2b9d42f0 1523
1524Returns the native character value of the first character in the string C<s>
1525which is assumed to be in UTF8 encoding; C<retlen> will be set to the
1526length, in bytes, of that character.
1527
1528Allows length and flags to be passed to low level routine.
1529
1530=cut
1531*/
1532/* On ASCII machines this is normally a macro but we want a
1533 real function in case XS code wants it
1534*/
1535#undef Perl_utf8n_to_uvchr
1536UV
37607a96 1537Perl_utf8n_to_uvchr(pTHX_ U8 *s, STRLEN curlen, STRLEN *retlen, U32 flags)
2b9d42f0 1538{
1539 UV uv = Perl_utf8n_to_uvuni(aTHX_ s, curlen, retlen, flags);
1540 return UNI_TO_NATIVE(uv);
1541}
1542
d2cc3551 1543/*
1544=for apidoc A|char *|pv_uni_display|SV *dsv|U8 *spv|STRLEN len|STRLEN pvlim|UV flags
1545
1546Build to the scalar dsv a displayable version of the string spv,
1547length len, the displayable version being at most pvlim bytes long
1548(if longer, the rest is truncated and "..." will be appended).
1549The flags argument is currently unused but available for future extensions.
1550The pointer to the PV of the dsv is returned.
1551
1552=cut */
e6b2e755 1553char *
1554Perl_pv_uni_display(pTHX_ SV *dsv, U8 *spv, STRLEN len, STRLEN pvlim, UV flags)
1555{
1556 int truncated = 0;
1557 char *s, *e;
1558
1559 sv_setpvn(dsv, "", 0);
1560 for (s = (char *)spv, e = s + len; s < e; s += UTF8SKIP(s)) {
1561 UV u;
1562 if (pvlim && SvCUR(dsv) >= pvlim) {
1563 truncated++;
1564 break;
1565 }
1566 u = utf8_to_uvchr((U8*)s, 0);
1567 Perl_sv_catpvf(aTHX_ dsv, "\\x{%"UVxf"}", u);
1568 }
1569 if (truncated)
1570 sv_catpvn(dsv, "...", 3);
1571
1572 return SvPVX(dsv);
1573}
2b9d42f0 1574
d2cc3551 1575/*
1576=for apidoc A|char *|sv_uni_display|SV *dsv|SV *ssv|STRLEN pvlim|UV flags
1577
1578Build to the scalar dsv a displayable version of the scalar sv,
1579he displayable version being at most pvlim bytes long
1580(if longer, the rest is truncated and "..." will be appended).
1581The flags argument is currently unused but available for future extensions.
1582The pointer to the PV of the dsv is returned.
1583
1584=cut */
e6b2e755 1585char *
1586Perl_sv_uni_display(pTHX_ SV *dsv, SV *ssv, STRLEN pvlim, UV flags)
1587{
701a277b 1588 return Perl_pv_uni_display(aTHX_ dsv, (U8*)SvPVX(ssv), SvCUR(ssv),
1589 pvlim, flags);
1590}
1591
d2cc3551 1592/*
1593=for apidoc A|I32|ibcmp_utf8|const char *s1|bool u1|const char *s2|bool u2|register I32 len
1594
1595Return true if the strings s1 and s2 differ case-insensitively, false
1596if not (if they are equal case-insensitively). If u1 is true, the
1597string s1 is assumed to be in UTF-8-encoded Unicode. If u2 is true,
332ddc25 1598the string s2 is assumed to be in UTF-8-encoded Unicode.
d2cc3551 1599
1600For case-insensitiveness, the "casefolding" of Unicode is used
1601instead of upper/lowercasing both the characters, see
1602http://www.unicode.org/unicode/reports/tr21/ (Case Mappings).
1603
1604=cut */
701a277b 1605I32
332ddc25 1606Perl_ibcmp_utf8(pTHX_ const char *s1, bool u1, register I32 len1, const char *s2, bool u2, register I32 len2)
1607{
1608 register U8 *a = (U8*)s1;
1609 register U8 *b = (U8*)s2;
1610 register U8 *ae = b + len1;
1611 register U8 *be = b + len2;
1612 STRLEN la, lb;
1613 UV ca, cb;
1614 STRLEN ulen1, ulen2;
e7ae6809 1615 U8 tmpbuf1[UTF8_MAXLEN_FOLD+1];
1616 U8 tmpbuf2[UTF8_MAXLEN_FOLD+1];
332ddc25 1617
1618 while (a < ae && b < be) {
1619 if (u1) {
1620 if (a + UTF8SKIP(a) > ae)
1621 break;
1622 ca = utf8_to_uvchr((U8*)a, &la);
1623 } else {
1624 ca = *a;
1625 la = 1;
1626 }
1627 if (u2) {
1628 if (b + UTF8SKIP(b) > be)
1629 break;
1630 cb = utf8_to_uvchr((U8*)b, &lb);
1631 } else {
1632 cb = *b;
1633 lb = 1;
1634 }
1635 if (ca != cb) {
701a277b 1636 if (u1)
332ddc25 1637 to_uni_fold(NATIVE_TO_UNI(ca), tmpbuf1, &ulen1);
1638 else
1639 ulen1 = 1;
701a277b 1640 if (u2)
332ddc25 1641 to_uni_fold(NATIVE_TO_UNI(cb), tmpbuf2, &ulen2);
1642 else
1643 ulen2 = 1;
1644 if (ulen1 != ulen2
1645 || (ulen1 == 1 && PL_fold[ca] != PL_fold[cb])
1646 || memNE((char *)tmpbuf1, (char *)tmpbuf2, ulen1))
1647 return 1; /* mismatch */
701a277b 1648 }
332ddc25 1649 a += la;
1650 b += lb;
d2cc3551 1651 }
332ddc25 1652 return a == ae && b == be ? 0 : 1; /* 0 match, 1 mismatch */
e6b2e755 1653}
701a277b 1654