X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/660a461690361c615b3b45ef731dd3d6f0d55d01..ff37711f3dc217d8c80194e5d2f37ccc7a7bc806:/utf8.c diff --git a/utf8.c b/utf8.c index bb8a67c..7d85a88 100644 --- a/utf8.c +++ b/utf8.c @@ -1,7 +1,7 @@ /* utf8.c * - * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 by Larry Wall and - * others + * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * 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. @@ -25,6 +25,13 @@ #define PERL_IN_UTF8_C #include "perl.h" +#ifndef EBCDIC +/* Separate prototypes needed because in ASCII systems these + * usually macros but they still are compiled as code, too. */ +PERL_CALLCONV UV Perl_utf8n_to_uvchr(pTHX_ const U8 *s, STRLEN curlen, STRLEN *retlen, U32 flags); +PERL_CALLCONV U8* Perl_uvchr_to_utf8(pTHX_ U8 *d, UV uv); +#endif + static const char unees[] = "Malformed UTF-8 character (unexpected end of string)"; @@ -186,7 +193,7 @@ five bytes or more. =cut */ STATIC STRLEN -S_is_utf8_char_slow(pTHX_ const U8 *s, const STRLEN len) +S_is_utf8_char_slow(const U8 *s, const STRLEN len) { U8 u = *s; STRLEN slen; @@ -238,6 +245,7 @@ STRLEN Perl_is_utf8_char(pTHX_ const U8 *s) { const STRLEN len = UTF8SKIP(s); + PERL_UNUSED_CONTEXT; #ifdef IS_UTF8_CHAR if (IS_UTF8_CHAR_FAST(len)) return IS_UTF8_CHAR(s, len) ? len : 0; @@ -261,12 +269,10 @@ See also is_utf8_string_loclen() and is_utf8_string_loc(). bool Perl_is_utf8_string(pTHX_ const U8 *s, STRLEN len) { + const U8* const send = s + (len ? len : strlen((const char *)s)); const U8* x = s; - const U8* send; - if (!len) - len = strlen((const char *)s); - send = s + len; + PERL_UNUSED_CONTEXT; while (x < send) { STRLEN c; @@ -281,9 +287,10 @@ Perl_is_utf8_string(pTHX_ const U8 *s, STRLEN len) c = UTF8SKIP(x); if (IS_UTF8_CHAR_FAST(c)) { if (!IS_UTF8_CHAR(x, c)) - goto out; - } else if (!is_utf8_char_slow(x, c)) - goto out; + c = 0; + } + else + c = is_utf8_char_slow(x, c); #else c = is_utf8_char(x); #endif /* #ifdef IS_UTF8_CHAR */ @@ -326,15 +333,11 @@ See also is_utf8_string_loc() and is_utf8_string(). bool Perl_is_utf8_string_loclen(pTHX_ const U8 *s, STRLEN len, const U8 **ep, STRLEN *el) { + const U8* const send = s + (len ? len : strlen((const char *)s)); const U8* x = s; - const U8* send; STRLEN c; - - if (!len) - len = strlen((const char *)s); - send = s + len; - if (el) - *el = 0; + STRLEN outlen = 0; + PERL_UNUSED_CONTEXT; while (x < send) { /* Inline the easy bits of is_utf8_char() here for speed... */ @@ -358,17 +361,16 @@ Perl_is_utf8_string_loclen(pTHX_ const U8 *s, STRLEN len, const U8 **ep, STRLEN goto out; } x += c; - if (el) - (*el)++; + outlen++; } out: + if (el) + *el = outlen; + if (ep) *ep = x; - if (x != send) - return FALSE; - - return TRUE; + return (x == send); } /* @@ -399,7 +401,8 @@ Most code should use utf8_to_uvchr() rather than call this directly. UV Perl_utf8n_to_uvuni(pTHX_ const U8 *s, STRLEN curlen, STRLEN *retlen, U32 flags) { - const U8 *s0 = s; + dVAR; + const U8 * const s0 = s; UV uv = *s, ouv = 0; STRLEN len = 1; const bool dowarn = ckWARN_d(WARN_UTF8); @@ -528,17 +531,17 @@ malformed: if (flags & UTF8_CHECK_ONLY) { if (retlen) - *retlen = -1; + *retlen = ((STRLEN) -1); return 0; } if (dowarn) { - SV* const sv = sv_2mortal(newSVpv("Malformed UTF-8 character ", 0)); + SV* const sv = sv_2mortal(newSVpvs("Malformed UTF-8 character ")); switch (warning) { case 0: /* Intentionally empty. */ break; case UTF8_WARN_EMPTY: - Perl_sv_catpv(aTHX_ sv, "(empty string)"); + sv_catpvs(sv, "(empty string)"); break; case UTF8_WARN_CONTINUATION: Perl_sv_catpvf(aTHX_ sv, "(unexpected continuation byte 0x%02"UVxf", with no preceding start byte)", uv); @@ -577,7 +580,7 @@ malformed: Perl_sv_catpvf(aTHX_ sv, "(character 0x%04"UVxf")", uv); break; default: - Perl_sv_catpv(aTHX_ sv, "(unknown reason)"); + sv_catpvs(sv, "(unknown reason)"); break; } @@ -655,7 +658,9 @@ up past C, croaks. STRLEN Perl_utf8_length(pTHX_ const U8 *s, const U8 *e) { + dVAR; STRLEN len = 0; + U8 t = 0; /* Note: cannot use UTF8_IS_...() too eagerly here since e.g. * the bitops (especially ~) can create illegal UTF-8. @@ -664,7 +669,7 @@ Perl_utf8_length(pTHX_ const U8 *s, const U8 *e) if (e < s) goto warn_and_return; while (s < e) { - const U8 t = UTF8SKIP(s); + t = UTF8SKIP(s); if (e - s < t) { warn_and_return: if (ckWARN_d(WARN_UTF8)) { @@ -698,42 +703,7 @@ same UTF-8 buffer. IV Perl_utf8_distance(pTHX_ const U8 *a, const U8 *b) { - IV off = 0; - - /* Note: cannot use UTF8_IS_...() too eagerly here since e.g. - * the bitops (especially ~) can create illegal UTF-8. - * In other words: in Perl UTF-8 is not just for Unicode. */ - - if (a < b) { - while (a < b) { - const U8 c = UTF8SKIP(a); - if (b - a < c) - goto warn_and_return; - a += c; - off--; - } - } - else { - while (b < a) { - const U8 c = UTF8SKIP(b); - - if (a - b < c) { - warn_and_return: - if (ckWARN_d(WARN_UTF8)) { - if (PL_op) - Perl_warner(aTHX_ packWARN(WARN_UTF8), - "%s in %s", unees, OP_DESC(PL_op)); - else - Perl_warner(aTHX_ packWARN(WARN_UTF8), unees); - } - return off; - } - b += c; - off++; - } - } - - return off; + return (a < b) ? -1 * (IV) utf8_length(a, b) : (IV) utf8_length(b, a); } /* @@ -752,6 +722,7 @@ on the first byte of character or just after the last byte of a character. U8 * Perl_utf8_hop(pTHX_ const U8 *s, I32 off) { + PERL_UNUSED_CONTEXT; /* Note: cannot use UTF8_IS_...() too eagerly here since e.g * the bitops (especially ~) can create illegal UTF-8. * In other words: in Perl UTF-8 is not just for Unicode. */ @@ -778,24 +749,26 @@ Unlike C, this over-writes the original string, and updates len to contain the new length. Returns zero on failure, setting C to -1. +If you need a copy of the string, see C. + =cut */ U8 * Perl_utf8_to_bytes(pTHX_ U8 *s, STRLEN *len) { - U8 *send; + U8 * const save = s; + U8 * const send = s + *len; U8 *d; - U8 *save = s; /* ensure valid UTF-8 and chars < 256 before updating string */ - for (send = s + *len; s < send; ) { + while (s < send) { U8 c = *s++; if (!UTF8_IS_INVARIANT(c) && (!UTF8_IS_DOWNGRADEABLE_START(c) || (s >= send) || !(c = *s++) || !UTF8_IS_CONTINUATION(c))) { - *len = -1; + *len = ((STRLEN) -1); return 0; } } @@ -832,6 +805,7 @@ Perl_bytes_from_utf8(pTHX_ const U8 *s, STRLEN *len, bool *is_utf8) const U8 *send; I32 count = 0; + PERL_UNUSED_CONTEXT; if (!*is_utf8) return (U8 *)start; @@ -847,9 +821,9 @@ Perl_bytes_from_utf8(pTHX_ const U8 *s, STRLEN *len, bool *is_utf8) } } - *is_utf8 = 0; + *is_utf8 = FALSE; - Newxz(d, (*len) - count + 1, U8); + Newx(d, (*len) - count + 1, U8); s = start; start = d; while (s < send) { U8 c = *s++; @@ -884,8 +858,9 @@ Perl_bytes_to_utf8(pTHX_ const U8 *s, STRLEN *len) const U8 * const send = s + (*len); U8 *d; U8 *dst; + PERL_UNUSED_CONTEXT; - Newxz(d, (*len) * 2 + 1, U8); + Newx(d, (*len) * 2 + 1, U8); dst = d; while (s < send) { @@ -921,7 +896,7 @@ Perl_utf16_to_utf8(pTHX_ U8* p, U8* d, I32 bytelen, I32 *newlen) } if (bytelen & 1) - Perl_croak(aTHX_ "panic: utf16_to_utf8: odd bytelen %"UVf, (UV)bytelen); + Perl_croak(aTHX_ "panic: utf16_to_utf8: odd bytelen %"UVuf, (UV)bytelen); pend = p + bytelen; @@ -929,7 +904,11 @@ Perl_utf16_to_utf8(pTHX_ U8* p, U8* d, I32 bytelen, I32 *newlen) UV uv = (p[0] << 8) + p[1]; /* UTF-16BE */ p += 2; if (uv < 0x80) { +#ifdef EBCDIC + *d++ = UNI_TO_NATIVE(uv); +#else *d++ = (U8)uv; +#endif continue; } if (uv < 0x800) { @@ -968,9 +947,9 @@ U8* Perl_utf16_to_utf8_reversed(pTHX_ U8* p, U8* d, I32 bytelen, I32 *newlen) { U8* s = (U8*)p; - U8* send = s + bytelen; + U8* const send = s + bytelen; while (s < send) { - U8 tmp = s[0]; + const U8 tmp = s[0]; s[0] = s[1]; s[1] = tmp; s += 2; @@ -1240,6 +1219,7 @@ static bool S_is_utf8_common(pTHX_ const U8 *const p, SV **swash, const char *const swashname) { + dVAR; if (!is_utf8_char(p)) return FALSE; if (!*swash) @@ -1250,105 +1230,121 @@ S_is_utf8_common(pTHX_ const U8 *const p, SV **swash, bool Perl_is_utf8_alnum(pTHX_ const U8 *p) { + dVAR; /* NOTE: "IsWord", not "IsAlnum", since Alnum is a true * descendant of isalnum(3), in other words, it doesn't * contain the '_'. --jhi */ - return S_is_utf8_common(aTHX_ p, &PL_utf8_alnum, "IsWord"); + return is_utf8_common(p, &PL_utf8_alnum, "IsWord"); } bool Perl_is_utf8_alnumc(pTHX_ const U8 *p) { - return S_is_utf8_common(aTHX_ p, &PL_utf8_alnumc, "IsAlnumC"); + dVAR; + return is_utf8_common(p, &PL_utf8_alnumc, "IsAlnumC"); } bool Perl_is_utf8_idfirst(pTHX_ const U8 *p) /* The naming is historical. */ { + dVAR; if (*p == '_') return TRUE; /* is_utf8_idstart would be more logical. */ - return S_is_utf8_common(aTHX_ p, &PL_utf8_idstart, "IdStart"); + return is_utf8_common(p, &PL_utf8_idstart, "IdStart"); } bool Perl_is_utf8_idcont(pTHX_ const U8 *p) { + dVAR; if (*p == '_') return TRUE; - return S_is_utf8_common(aTHX_ p, &PL_utf8_idcont, "IdContinue"); + return is_utf8_common(p, &PL_utf8_idcont, "IdContinue"); } bool Perl_is_utf8_alpha(pTHX_ const U8 *p) { - return S_is_utf8_common(aTHX_ p, &PL_utf8_alpha, "IsAlpha"); + dVAR; + return is_utf8_common(p, &PL_utf8_alpha, "IsAlpha"); } bool Perl_is_utf8_ascii(pTHX_ const U8 *p) { - return S_is_utf8_common(aTHX_ p, &PL_utf8_ascii, "IsAscii"); + dVAR; + return is_utf8_common(p, &PL_utf8_ascii, "IsAscii"); } bool Perl_is_utf8_space(pTHX_ const U8 *p) { - return S_is_utf8_common(aTHX_ p, &PL_utf8_space, "IsSpacePerl"); + dVAR; + return is_utf8_common(p, &PL_utf8_space, "IsSpacePerl"); } bool Perl_is_utf8_digit(pTHX_ const U8 *p) { - return S_is_utf8_common(aTHX_ p, &PL_utf8_digit, "IsDigit"); + dVAR; + return is_utf8_common(p, &PL_utf8_digit, "IsDigit"); } bool Perl_is_utf8_upper(pTHX_ const U8 *p) { - return S_is_utf8_common(aTHX_ p, &PL_utf8_upper, "IsUppercase"); + dVAR; + return is_utf8_common(p, &PL_utf8_upper, "IsUppercase"); } bool Perl_is_utf8_lower(pTHX_ const U8 *p) { - return S_is_utf8_common(aTHX_ p, &PL_utf8_lower, "IsLowercase"); + dVAR; + return is_utf8_common(p, &PL_utf8_lower, "IsLowercase"); } bool Perl_is_utf8_cntrl(pTHX_ const U8 *p) { - return S_is_utf8_common(aTHX_ p, &PL_utf8_cntrl, "IsCntrl"); + dVAR; + return is_utf8_common(p, &PL_utf8_cntrl, "IsCntrl"); } bool Perl_is_utf8_graph(pTHX_ const U8 *p) { - return S_is_utf8_common(aTHX_ p, &PL_utf8_graph, "IsGraph"); + dVAR; + return is_utf8_common(p, &PL_utf8_graph, "IsGraph"); } bool Perl_is_utf8_print(pTHX_ const U8 *p) { - return S_is_utf8_common(aTHX_ p, &PL_utf8_print, "IsPrint"); + dVAR; + return is_utf8_common(p, &PL_utf8_print, "IsPrint"); } bool Perl_is_utf8_punct(pTHX_ const U8 *p) { - return S_is_utf8_common(aTHX_ p, &PL_utf8_punct, "IsPunct"); + dVAR; + return is_utf8_common(p, &PL_utf8_punct, "IsPunct"); } bool Perl_is_utf8_xdigit(pTHX_ const U8 *p) { - return S_is_utf8_common(aTHX_ p, &PL_utf8_xdigit, "Isxdigit"); + dVAR; + return is_utf8_common(p, &PL_utf8_xdigit, "Isxdigit"); } bool Perl_is_utf8_mark(pTHX_ const U8 *p) { - return S_is_utf8_common(aTHX_ p, &PL_utf8_mark, "IsM"); + dVAR; + return is_utf8_common(p, &PL_utf8_mark, "IsM"); } /* @@ -1380,6 +1376,7 @@ UV Perl_to_utf8_case(pTHX_ const U8 *p, U8* ustrp, STRLEN *lenp, SV **swashp, const char *normal, const char *special) { + dVAR; U8 tmpbuf[UTF8_MAXBYTES_CASE+1]; STRLEN len = 0; @@ -1397,10 +1394,10 @@ Perl_to_utf8_case(pTHX_ const U8 *p, U8* ustrp, STRLEN *lenp, if (special && (uv1 == 0xDF || uv1 > 0xFF)) { /* It might be "special" (sometimes, but not always, * a multicharacter mapping) */ - HV *hv; + HV * const hv = get_hv(special, FALSE); SV **svp; - if ((hv = get_hv(special, FALSE)) && + if (hv && (svp = hv_fetch(hv, (const char*)tmpbuf, UNISKIP(uv1), FALSE)) && (*svp)) { const char *s; @@ -1420,7 +1417,7 @@ Perl_to_utf8_case(pTHX_ const U8 *p, U8* ustrp, STRLEN *lenp, STRLEN tlen = 0; while (t < tend) { - UV c = utf8_to_uvchr(t, &tlen); + const UV c = utf8_to_uvchr(t, &tlen); if (tlen > 0) { d = uvchr_to_utf8(d, UNI_TO_NATIVE(c)); t += tlen; @@ -1445,12 +1442,11 @@ Perl_to_utf8_case(pTHX_ const U8 *p, U8* ustrp, STRLEN *lenp, } if (!len && *swashp) { - UV uv2 = swash_fetch(*swashp, tmpbuf, TRUE); - + const UV uv2 = swash_fetch(*swashp, tmpbuf, TRUE); + if (uv2) { /* It was "normal" (a single character mapping). */ - UV uv3 = UNI_TO_NATIVE(uv2); - + const UV uv3 = UNI_TO_NATIVE(uv2); len = uvchr_to_utf8(ustrp, uv3) - ustrp; } } @@ -1480,6 +1476,7 @@ The first character of the uppercased version is returned UV Perl_to_utf8_upper(pTHX_ const U8 *p, U8* ustrp, STRLEN *lenp) { + dVAR; return Perl_to_utf8_case(aTHX_ p, ustrp, lenp, &PL_utf8_toupper, "ToUpper", "utf8::ToSpecUpper"); } @@ -1500,6 +1497,7 @@ The first character of the titlecased version is returned UV Perl_to_utf8_title(pTHX_ const U8 *p, U8* ustrp, STRLEN *lenp) { + dVAR; return Perl_to_utf8_case(aTHX_ p, ustrp, lenp, &PL_utf8_totitle, "ToTitle", "utf8::ToSpecTitle"); } @@ -1520,6 +1518,7 @@ The first character of the lowercased version is returned UV Perl_to_utf8_lower(pTHX_ const U8 *p, U8* ustrp, STRLEN *lenp) { + dVAR; return Perl_to_utf8_case(aTHX_ p, ustrp, lenp, &PL_utf8_tolower, "ToLower", "utf8::ToSpecLower"); } @@ -1541,6 +1540,7 @@ The first character of the foldcased version is returned UV Perl_to_utf8_fold(pTHX_ const U8 *p, U8* ustrp, STRLEN *lenp) { + dVAR; return Perl_to_utf8_case(aTHX_ p, ustrp, lenp, &PL_utf8_tofold, "ToFold", "utf8::ToSpecFold"); } @@ -1571,8 +1571,15 @@ Perl_swash_init(pTHX_ const char* pkg, const char* name, SV *listsv, I32 minbits if (!gv_fetchmeth(stash, "SWASHNEW", 8, -1)) { /* demand load utf8 */ ENTER; errsv_save = newSVsv(ERRSV); + /* It is assumed that callers of this routine are not passing in any + user derived data. */ + /* Need to do this after save_re_context() as it will set PL_tainted to + 1 while saving $1 etc (see the code after getrx: in Perl_magic_get). + Even line to create errsv_save can turn on PL_tainted. */ + SAVEBOOL(PL_tainted); + PL_tainted = 0; Perl_load_module(aTHX_ PERL_LOADMOD_NOIMPORT, newSVpvn(pkg,pkg_len), - Nullsv); + NULL); if (!SvTRUE(ERRSV)) sv_setsv(ERRSV, errsv_save); SvREFCNT_dec(errsv_save); @@ -1608,12 +1615,12 @@ Perl_swash_init(pTHX_ const char* pkg, const char* name, SV *listsv, I32 minbits const char* const pv = SvPV_const(tokenbufsv, len); Copy(pv, PL_tokenbuf, len+1, char); - PL_curcop->op_private = (U8)(PL_hints & HINT_PRIVATE_MASK); + CopHINTS_set(PL_curcop, PL_hints); } if (!SvROK(retval) || SvTYPE(SvRV(retval)) != SVt_PVHV) { if (SvPOK(retval)) Perl_croak(aTHX_ "Can't find Unicode property definition \"%"SVf"\"", - retval); + SVfARG(retval)); Perl_croak(aTHX_ "SWASHNEW didn't return an HV ref"); } return retval; @@ -1626,11 +1633,18 @@ Perl_swash_init(pTHX_ const char* pkg, const char* name, SV *listsv, I32 minbits * the lower-level routine, and it is similarly broken for returning * multiple values. --jhi */ /* Now SWASHGET is recasted into S_swash_get in this file. */ + +/* Note: + * Returns the value of property/mapping C for the first character + * of the string C. If C is true, the string C is + * assumed to be in utf8. If C is false, the string C is + * assumed to be in native 8-bit encoding. Caches the swatch in C. + */ UV -Perl_swash_fetch(pTHX_ SV *sv, const U8 *ptr, bool do_utf8) +Perl_swash_fetch(pTHX_ SV *swash, const U8 *ptr, bool do_utf8) { dVAR; - HV* const hv = (HV*)SvRV(sv); + HV* const hv = (HV*)SvRV(swash); U32 klen; U32 off; STRLEN slen; @@ -1639,7 +1653,7 @@ Perl_swash_fetch(pTHX_ SV *sv, const U8 *ptr, bool do_utf8) U32 bit; SV *swatch; U8 tmputf8[2]; - UV c = NATIVE_TO_ASCII(*ptr); + const UV c = NATIVE_TO_ASCII(*ptr); if (!do_utf8 && !UNI_IS_INVARIANT(c)) { tmputf8[0] = (U8)UTF8_EIGHT_BIT_HI(c); @@ -1696,13 +1710,13 @@ Perl_swash_fetch(pTHX_ SV *sv, const U8 *ptr, bool do_utf8) const UV code_point = utf8n_to_uvuni(ptr, UTF8_MAXBYTES, 0, ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANY); - swatch = swash_get(sv, + swatch = swash_get(swash, /* On EBCDIC & ~(0xA0-1) isn't a useful thing to do */ (klen) ? (code_point & ~(needents - 1)) : 0, needents); if (IN_PERL_COMPILETIME) - PL_curcop->op_private = (U8)(PL_hints & HINT_PRIVATE_MASK); + CopHINTS_set(PL_curcop, PL_hints); svp = hv_store(hv, (const char *)ptr, klen, swatch, 0); @@ -1735,7 +1749,7 @@ Perl_swash_fetch(pTHX_ SV *sv, const U8 *ptr, bool do_utf8) return (tmps[off] << 24) + (tmps[off+1] << 16) + (tmps[off+2] << 8) + tmps[off + 3] ; } Perl_croak(aTHX_ "panic: swash_fetch got swatch of unexpected bit width"); - return 0; + NORETURN_FUNCTION_END; } /* Note: @@ -1752,17 +1766,17 @@ S_swash_get(pTHX_ SV* swash, UV start, UV span) STRLEN lcur, xcur, scur; HV* const hv = (HV*)SvRV(swash); - SV** listsvp = hv_fetch(hv, "LIST", 4, FALSE); - SV** typesvp = hv_fetch(hv, "TYPE", 4, FALSE); - SV** bitssvp = hv_fetch(hv, "BITS", 4, FALSE); - SV** nonesvp = hv_fetch(hv, "NONE", 4, FALSE); - SV** extssvp = hv_fetch(hv, "EXTRAS", 6, FALSE); - U8* typestr = (U8*)SvPV_nolen(*typesvp); - int typeto = typestr[0] == 'T' && typestr[1] == 'o'; - STRLEN bits = SvUV(*bitssvp); - STRLEN octets = bits >> 3; /* if bits == 1, then octets == 0 */ - UV none = SvUV(*nonesvp); - UV end = start + span; + SV** const listsvp = hv_fetchs(hv, "LIST", FALSE); + SV** const typesvp = hv_fetchs(hv, "TYPE", FALSE); + SV** const bitssvp = hv_fetchs(hv, "BITS", FALSE); + SV** const nonesvp = hv_fetchs(hv, "NONE", FALSE); + SV** const extssvp = hv_fetchs(hv, "EXTRAS", FALSE); + const U8* const typestr = (U8*)SvPV_nolen(*typesvp); + const int typeto = typestr[0] == 'T' && typestr[1] == 'o'; + const STRLEN bits = SvUV(*bitssvp); + const STRLEN octets = bits >> 3; /* if bits == 1, then octets == 0 */ + const UV none = SvUV(*nonesvp); + const UV end = start + span; if (bits != 1 && bits != 8 && bits != 16 && bits != 32) { Perl_croak(aTHX_ "panic: swash_get doesn't expect bits %"UVuf, @@ -1770,12 +1784,12 @@ S_swash_get(pTHX_ SV* swash, UV start, UV span) } /* create and initialize $swatch */ - swatch = newSVpvn("",0); + swatch = newSVpvs(""); scur = octets ? (span * octets) : (span + 7) / 8; SvGROW(swatch, scur + 1); s = (U8*)SvPVX(swatch); if (octets && none) { - const U8* e = s + scur; + const U8* const e = s + scur; while (s < e) { if (bits == 8) *s++ = (U8)(none & 0xff); @@ -1802,11 +1816,11 @@ S_swash_get(pTHX_ SV* swash, UV start, UV span) l = (U8*)SvPV(*listsvp, lcur); lend = l + lcur; while (l < lend) { - UV min, max, val, key; + UV min, max, val; STRLEN numlen; I32 flags = PERL_SCAN_SILENT_ILLDIGIT | PERL_SCAN_DISALLOW_PREFIX; - U8* nl = (U8*)memchr(l, '\n', lend - l); + U8* const nl = (U8*)memchr(l, '\n', lend - l); numlen = lend - l; min = grok_hex((char *)l, &numlen, &flags, NULL); @@ -1875,6 +1889,7 @@ S_swash_get(pTHX_ SV* swash, UV start, UV span) continue; if (octets) { + UV key; if (min < start) { if (!none || val < none) { val += start - min; @@ -1905,10 +1920,11 @@ S_swash_get(pTHX_ SV* swash, UV start, UV span) } } else { /* bits == 1, then val should be ignored */ + UV key; if (min < start) min = start; for (key = min; key <= max; key++) { - STRLEN offset = (STRLEN)(key - start); + const STRLEN offset = (STRLEN)(key - start); if (key >= end) goto go_out_list; s[offset >> 3] |= 1 << (offset & 7); @@ -1930,7 +1946,7 @@ S_swash_get(pTHX_ SV* swash, UV start, UV span) U8 *s, *o, *nl; STRLEN slen, olen; - U8 opc = *x++; + const U8 opc = *x++; if (opc == '\n') continue; @@ -1959,7 +1975,7 @@ S_swash_get(pTHX_ SV* swash, UV start, UV span) othersvp = hv_fetch(hv, (char *)namestr, namelen, FALSE); otherhv = (HV*)SvRV(*othersvp); - otherbitssvp = hv_fetch(otherhv, "BITS", 4, FALSE); + otherbitssvp = hv_fetchs(otherhv, "BITS", FALSE); otherbits = (STRLEN)SvUV(*otherbitssvp); if (bits < otherbits) Perl_croak(aTHX_ "panic: swash_get found swatch size mismatch"); @@ -2000,7 +2016,7 @@ S_swash_get(pTHX_ SV* swash, UV start, UV span) else { STRLEN otheroctets = otherbits >> 3; STRLEN offset = 0; - U8* send = s + slen; + U8* const send = s + slen; while (s < send) { UV otherval = 0; @@ -2019,7 +2035,7 @@ S_swash_get(pTHX_ SV* swash, UV start, UV span) } if (opc == '+' && otherval) - ; /* replace with otherval */ + NOOP; /* replace with otherval */ else if (opc == '!' && !otherval) otherval = 1; else if (opc == '-' && otherval) @@ -2144,7 +2160,7 @@ Perl_pv_uni_display(pTHX_ SV *dsv, const U8 *spv, STRLEN len, STRLEN pvlim, UV f u = utf8_to_uvchr((U8*)s, 0); if (u < 256) { const unsigned char c = (unsigned char)u & 0xFF; - if (!ok && (flags & UNI_DISPLAY_BACKSLASH)) { + if (flags & UNI_DISPLAY_BACKSLASH) { switch (c) { case '\n': ok = 'n'; break; @@ -2174,7 +2190,7 @@ Perl_pv_uni_display(pTHX_ SV *dsv, const U8 *spv, STRLEN len, STRLEN pvlim, UV f Perl_sv_catpvf(aTHX_ dsv, "\\x{%"UVxf"}", u); } if (truncated) - sv_catpvn(dsv, "...", 3); + sv_catpvs(dsv, "..."); return SvPVX(dsv); } @@ -2190,7 +2206,8 @@ The flags argument is as in pv_uni_display(). The pointer to the PV of the dsv is returned. -=cut */ +=cut +*/ char * Perl_sv_uni_display(pTHX_ SV *dsv, SV *ssv, STRLEN pvlim, UV flags) { @@ -2226,11 +2243,15 @@ http://www.unicode.org/unicode/reports/tr21/ (Case Mappings). I32 Perl_ibcmp_utf8(pTHX_ const char *s1, char **pe1, register UV l1, bool u1, const char *s2, char **pe2, register UV l2, bool u2) { + dVAR; register const U8 *p1 = (const U8*)s1; register const U8 *p2 = (const U8*)s2; - register const U8 *f1 = 0, *f2 = 0; - register U8 *e1 = 0, *q1 = 0; - register U8 *e2 = 0, *q2 = 0; + register const U8 *f1 = NULL; + register const U8 *f2 = NULL; + register U8 *e1 = NULL; + register U8 *q1 = NULL; + register U8 *e2 = NULL; + register U8 *q2 = NULL; STRLEN n1 = 0, n2 = 0; U8 foldbuf1[UTF8_MAXBYTES_CASE+1]; U8 foldbuf2[UTF8_MAXBYTES_CASE+1];