Move DynaLoader.o into libperl.so.
[p5sagit/p5-mst-13.2.git] / utf8.c
diff --git a/utf8.c b/utf8.c
index 813a64f..e5079cb 100644 (file)
--- 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,
+ *    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.
@@ -186,7 +186,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 +238,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;
@@ -264,6 +265,7 @@ Perl_is_utf8_string(pTHX_ const U8 *s, STRLEN len)
     const U8* x = s;
     const U8* send;
 
+    PERL_UNUSED_CONTEXT;
     if (!len)
        len = strlen((const char *)s);
     send = s + len;
@@ -329,6 +331,7 @@ Perl_is_utf8_string_loclen(pTHX_ const U8 *s, STRLEN len, const U8 **ep, STRLEN
     const U8* x = s;
     const U8* send;
     STRLEN c;
+    PERL_UNUSED_CONTEXT;
 
     if (!len)
         len = strlen((const char *)s);
@@ -399,6 +402,7 @@ 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)
 {
+    dVAR;
     const U8 *s0 = s;
     UV uv = *s, ouv = 0;
     STRLEN len = 1;
@@ -533,12 +537,12 @@ malformed:
     }
 
     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 +581,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,6 +659,7 @@ up past C<e>, croaks.
 STRLEN
 Perl_utf8_length(pTHX_ const U8 *s, const U8 *e)
 {
+    dVAR;
     STRLEN len = 0;
 
     /* Note: cannot use UTF8_IS_...() too eagerly here since e.g.
@@ -698,6 +703,7 @@ same UTF-8 buffer.
 IV
 Perl_utf8_distance(pTHX_ const U8 *a, const U8 *b)
 {
+    dVAR;
     IV off = 0;
 
     /* Note: cannot use UTF8_IS_...() too eagerly here since  e.g.
@@ -752,6 +758,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. */
@@ -832,6 +839,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;
 
@@ -849,7 +857,7 @@ Perl_bytes_from_utf8(pTHX_ const U8 *s, STRLEN *len, bool *is_utf8)
 
     *is_utf8 = 0;              
 
-    Newxz(d, (*len) - count + 1, U8);
+    Newx(d, (*len) - count + 1, U8);
     s = start; start = d;
     while (s < send) {
        U8 c = *s++;
@@ -884,8 +892,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) {
@@ -1240,16 +1249,18 @@ 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)
-       *swash = swash_init("utf8", swashname, &PL_sv_undef, 0, 0);
+       *swash = swash_init("utf8", swashname, &PL_sv_undef, 1, 0);
     return swash_fetch(*swash, p, TRUE) != 0;
 }
 
 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 */
@@ -1259,12 +1270,14 @@ Perl_is_utf8_alnum(pTHX_ const U8 *p)
 bool
 Perl_is_utf8_alnumc(pTHX_ const U8 *p)
 {
+    dVAR;
     return S_is_utf8_common(aTHX_ 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. */
@@ -1274,6 +1287,7 @@ Perl_is_utf8_idfirst(pTHX_ const U8 *p) /* The naming is historical. */
 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");
@@ -1282,72 +1296,84 @@ Perl_is_utf8_idcont(pTHX_ const U8 *p)
 bool
 Perl_is_utf8_alpha(pTHX_ const U8 *p)
 {
+    dVAR;
     return S_is_utf8_common(aTHX_ p, &PL_utf8_alpha, "IsAlpha");
 }
 
 bool
 Perl_is_utf8_ascii(pTHX_ const U8 *p)
 {
+    dVAR;
     return S_is_utf8_common(aTHX_ p, &PL_utf8_ascii, "IsAscii");
 }
 
 bool
 Perl_is_utf8_space(pTHX_ const U8 *p)
 {
+    dVAR;
     return S_is_utf8_common(aTHX_ p, &PL_utf8_space, "IsSpacePerl");
 }
 
 bool
 Perl_is_utf8_digit(pTHX_ const U8 *p)
 {
+    dVAR;
     return S_is_utf8_common(aTHX_ p, &PL_utf8_digit, "IsDigit");
 }
 
 bool
 Perl_is_utf8_upper(pTHX_ const U8 *p)
 {
+    dVAR;
     return S_is_utf8_common(aTHX_ p, &PL_utf8_upper, "IsUppercase");
 }
 
 bool
 Perl_is_utf8_lower(pTHX_ const U8 *p)
 {
+    dVAR;
     return S_is_utf8_common(aTHX_ p, &PL_utf8_lower, "IsLowercase");
 }
 
 bool
 Perl_is_utf8_cntrl(pTHX_ const U8 *p)
 {
+    dVAR;
     return S_is_utf8_common(aTHX_ p, &PL_utf8_cntrl, "IsCntrl");
 }
 
 bool
 Perl_is_utf8_graph(pTHX_ const U8 *p)
 {
+    dVAR;
     return S_is_utf8_common(aTHX_ p, &PL_utf8_graph, "IsGraph");
 }
 
 bool
 Perl_is_utf8_print(pTHX_ const U8 *p)
 {
+    dVAR;
     return S_is_utf8_common(aTHX_ p, &PL_utf8_print, "IsPrint");
 }
 
 bool
 Perl_is_utf8_punct(pTHX_ const U8 *p)
 {
+    dVAR;
     return S_is_utf8_common(aTHX_ p, &PL_utf8_punct, "IsPunct");
 }
 
 bool
 Perl_is_utf8_xdigit(pTHX_ const U8 *p)
 {
+    dVAR;
     return S_is_utf8_common(aTHX_ p, &PL_utf8_xdigit, "Isxdigit");
 }
 
 bool
 Perl_is_utf8_mark(pTHX_ const U8 *p)
 {
+    dVAR;
     return S_is_utf8_common(aTHX_ p, &PL_utf8_mark, "IsM");
 }
 
@@ -1380,6 +1406,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;
 
@@ -1480,6 +1507,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 +1528,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 +1549,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,12 +1571,17 @@ 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");
 }
 
-/* a "swash" is a swatch hash */
-
+/* Note:
+ * A "swash" is a swatch hash.
+ * A "swatch" is a bit vector generated by utf8.c:S_swash_get().
+ * C<pkg> is a pointer to a package name for SWASHNEW, should be "utf8".
+ * For other parameters, see utf8::SWASHNEW in lib/utf8_heavy.pl.
+ */
 SV*
 Perl_swash_init(pTHX_ const char* pkg, const char* name, SV *listsv, I32 minbits, I32 none)
 {
@@ -1567,8 +1602,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);
@@ -1622,11 +1664,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<swash> for the first character
+ * of the string C<ptr>. If C<do_utf8> is true, the string C<ptr> is
+ * assumed to be in utf8. If C<do_utf8> is false, the string C<ptr> is
+ * assumed to be in native 8-bit encoding. Caches the swatch in C<swash>.
+ */
 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;
@@ -1692,7 +1741,7 @@ 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);
@@ -1704,7 +1753,7 @@ Perl_swash_fetch(pTHX_ SV *sv, const U8 *ptr, bool do_utf8)
 
            if (!svp || !(tmps = (U8*)SvPV(*svp, slen))
                     || (slen << 3) < needents)
-               Perl_croak(aTHX_ "The swatch does not have proper length");
+               Perl_croak(aTHX_ "panic: swash_fetch got improper swatch");
        }
 
        PL_last_swash_hv = hv;
@@ -1730,7 +1779,7 @@ Perl_swash_fetch(pTHX_ SV *sv, const U8 *ptr, bool do_utf8)
        off <<= 2;
        return (tmps[off] << 24) + (tmps[off+1] << 16) + (tmps[off+2] << 8) + tmps[off + 3] ;
     }
-    Perl_croak(aTHX_ "panic: swash_fetch");
+    Perl_croak(aTHX_ "panic: swash_fetch got swatch of unexpected bit width");
     return 0;
 }
 
@@ -1744,33 +1793,34 @@ STATIC SV*
 S_swash_get(pTHX_ SV* swash, UV start, UV span)
 {
     SV *swatch;
-    U8 *l, *lend, *x, *xend, *s, *nl;
+    U8 *l, *lend, *x, *xend, *s;
     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_ "swash_get: unknown bits %"UVuf, (UV) bits);
+       Perl_croak(aTHX_ "panic: swash_get doesn't expect bits %"UVuf,
+                                                (UV)bits);
     }
 
     /* 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);
@@ -1801,7 +1851,7 @@ S_swash_get(pTHX_ SV* swash, UV start, UV span)
        STRLEN numlen;
        I32 flags = PERL_SCAN_SILENT_ILLDIGIT | PERL_SCAN_DISALLOW_PREFIX;
 
-       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);
@@ -1846,6 +1896,8 @@ S_swash_get(pTHX_ SV* swash, UV start, UV span)
                    }
                }
            }
+           else
+               val = 0; /* bits == 1, then val should be ignored */
        }
        else {
            max = min;
@@ -1855,6 +1907,8 @@ S_swash_get(pTHX_ SV* swash, UV start, UV span)
                    Perl_croak(aTHX_ "%s: illegal mapping '%s'", typestr, l);
                }
            }
+           else
+               val = 0; /* bits == 1, then val should be ignored */
        }
 
        if (nl)
@@ -1895,11 +1949,11 @@ S_swash_get(pTHX_ SV* swash, UV start, UV span)
                    ++val;
            }
        }
-       else {
+       else { /* bits == 1, then val should be ignored */
            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);
@@ -1918,7 +1972,7 @@ S_swash_get(pTHX_ SV* swash, UV start, UV span)
        HV* otherhv;
        STRLEN otherbits;
        SV **otherbitssvp, *other;
-       U8 *s, *o;
+       U8 *s, *o, *nl;
        STRLEN slen, olen;
 
        U8 opc = *x++;
@@ -1949,28 +2003,23 @@ S_swash_get(pTHX_ SV* swash, UV start, UV span)
        }
 
        othersvp = hv_fetch(hv, (char *)namestr, namelen, FALSE);
-       if (*othersvp && SvROK(*othersvp) &&
-                        SvTYPE(SvRV(*othersvp))==SVt_PVHV)
-           otherhv = (HV*)SvRV(*othersvp);
-       else
-           Perl_croak(aTHX_ "otherhv is not a hash reference");
-
-       otherbitssvp = hv_fetch(otherhv, "BITS", 4, FALSE);
+       otherhv = (HV*)SvRV(*othersvp);
+       otherbitssvp = hv_fetchs(otherhv, "BITS", FALSE);
        otherbits = (STRLEN)SvUV(*otherbitssvp);
        if (bits < otherbits)
-           Perl_croak(aTHX_ "swash_get: swatch size mismatch");
+           Perl_croak(aTHX_ "panic: swash_get found swatch size mismatch");
 
        /* The "other" swatch must be destroyed after. */
        other = swash_get(*othersvp, start, span);
        o = (U8*)SvPV(other, olen);
 
        if (!olen)
-           Perl_croak(aTHX_ "swash_get didn't return valid swatch for other");
+           Perl_croak(aTHX_ "panic: swash_get got improper swatch");
 
        s = (U8*)SvPV(swatch, slen);
        if (bits == 1 && otherbits == 1) {
            if (slen != olen)
-               Perl_croak(aTHX_ "swash_get: swatch length mismatch");
+               Perl_croak(aTHX_ "panic: swash_get found swatch length mismatch");
 
            switch (opc) {
            case '+':
@@ -1993,8 +2042,7 @@ S_swash_get(pTHX_ SV* swash, UV start, UV span)
                break;
            }
        }
-       else { /* bits >= 8 */
-              /* XXX: but weirdly otherval is treated as boolean */
+       else {
            STRLEN otheroctets = otherbits >> 3;
            STRLEN offset = 0;
            U8* send = s + slen;
@@ -2015,8 +2063,8 @@ S_swash_get(pTHX_ SV* swash, UV start, UV span)
                    }
                }
 
-               if      (opc == '+' && otherval)
-                   otherval = 1;
+               if (opc == '+' && otherval)
+                   /*EMPTY*/;   /* replace with otherval */
                else if (opc == '!' && !otherval)
                    otherval = 1;
                else if (opc == '-' && otherval)
@@ -2024,7 +2072,7 @@ S_swash_get(pTHX_ SV* swash, UV start, UV span)
                else if (opc == '&' && !otherval)
                    otherval = 0;
                else {
-                   s += octets; /* not modify orig swatch */
+                   s += octets; /* no replacement */
                    continue;
                }
 
@@ -2141,7 +2189,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;
@@ -2171,7 +2219,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);
 }
@@ -2223,11 +2271,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];