X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=doop.c;h=9f0fa6466ac34e8c5ad41b5d743d7f7530f3a335;hb=d4742b2c4fb9d3d58f0b4211ec254bb804bb6fd5;hp=f6dbe67a6bf46f491a47e5095233eeb677cc1586;hpb=a0dbb04553005cdbafdeb7435a79ae500b5aa8ff;p=p5sagit%2Fp5-mst-13.2.git diff --git a/doop.c b/doop.c index f6dbe67..9f0fa64 100644 --- a/doop.c +++ b/doop.c @@ -29,13 +29,14 @@ S_do_trans_simple(pTHX_ SV *sv) U8 *send; U8 *dstart; I32 matches = 0; + I32 grows = PL_op->op_private & OPpTRANS_GROWS; STRLEN len; short *tbl; I32 ch; tbl = (short*)cPVOP->op_pv; if (!tbl) - Perl_croak(aTHX_ "panic: do_trans_simple"); + Perl_croak(aTHX_ "panic: do_trans_simple line %d",__LINE__); s = (U8*)SvPV(sv, len); send = s + len; @@ -55,47 +56,54 @@ S_do_trans_simple(pTHX_ SV *sv) } /* Allow for expansion: $_="a".chr(400); tr/a/\xFE/, FE needs encoding */ - Newz(0, d, len*2+1, U8); + if (grows) + New(0, d, len*2+1, U8); + else + d = s; dstart = d; while (s < send) { STRLEN ulen; - short c; + UV c; - ulen = 1; /* Need to check this, otherwise 128..255 won't match */ - c = utf8_to_uv(s, send - s, &ulen, 0); - if (c < 0x100 && (ch = tbl[(short)c]) >= 0) { + c = utf8n_to_uvchr(s, send - s, &ulen, 0); + if (c < 0x100 && (ch = tbl[c]) >= 0) { matches++; - if (ch < 0x80) - *d++ = ch; - else - d = uv_to_utf8(d,ch); + d = uvchr_to_utf8(d, ch); s += ulen; } else { /* No match -> copy */ - while (ulen--) - *d++ = *s++; + Copy(s, d, ulen, U8); + d += ulen; + s += ulen; } } - *d = '\0'; - sv_setpvn(sv, (char*)dstart, d - dstart); + if (grows) { + sv_setpvn(sv, (char*)dstart, d - dstart); + Safefree(dstart); + } + else { + *d = '\0'; + SvCUR_set(sv, d - dstart); + } SvUTF8_on(sv); SvSETMAGIC(sv); return matches; } STATIC I32 -S_do_trans_count(pTHX_ SV *sv)/* SPC - OK */ +S_do_trans_count(pTHX_ SV *sv) { U8 *s; U8 *send; I32 matches = 0; STRLEN len; short *tbl; + I32 complement = PL_op->op_private & OPpTRANS_COMPLEMENT; tbl = (short*)cPVOP->op_pv; if (!tbl) - Perl_croak(aTHX_ "panic: do_trans_count"); + Perl_croak(aTHX_ "panic: do_trans_count line %d",__LINE__); s = (U8*)SvPV(sv, len); send = s + len; @@ -109,8 +117,11 @@ S_do_trans_count(pTHX_ SV *sv)/* SPC - OK */ while (s < send) { UV c; STRLEN ulen; - c = utf8_to_uv(s, send - s, &ulen, 0); - if (c < 0x100 && tbl[c] >= 0) + c = utf8n_to_uvchr(s, send - s, &ulen, 0); + if (c < 0x100) { + if (tbl[c] >= 0) + matches++; + } else if (complement) matches++; s += ulen; } @@ -119,7 +130,7 @@ S_do_trans_count(pTHX_ SV *sv)/* SPC - OK */ } STATIC I32 -S_do_trans_complex(pTHX_ SV *sv)/* SPC - NOT OK */ +S_do_trans_complex(pTHX_ SV *sv) { U8 *s; U8 *send; @@ -127,13 +138,16 @@ S_do_trans_complex(pTHX_ SV *sv)/* SPC - NOT OK */ U8 *dstart; I32 isutf8; I32 matches = 0; - STRLEN len; + I32 grows = PL_op->op_private & OPpTRANS_GROWS; + I32 complement = PL_op->op_private & OPpTRANS_COMPLEMENT; + I32 del = PL_op->op_private & OPpTRANS_DELETE; + STRLEN len, rlen = 0; short *tbl; I32 ch; tbl = (short*)cPVOP->op_pv; if (!tbl) - Perl_croak(aTHX_ "panic: do_trans_complex"); + Perl_croak(aTHX_ "panic: do_trans_complex line %d",__LINE__); s = (U8*)SvPV(sv, len); isutf8 = SvUTF8(sv); @@ -170,32 +184,61 @@ S_do_trans_complex(pTHX_ SV *sv)/* SPC - NOT OK */ s++; } } + *d = '\0'; SvCUR_set(sv, d - dstart); } else { /* isutf8 */ - Newz(0, d, len*2+1, U8); + if (grows) + New(0, d, len*2+1, U8); + else + d = s; dstart = d; + if (complement && !del) + rlen = tbl[0x100]; + +#ifdef MACOS_TRADITIONAL +#define comp CoMP /* "comp" is a keyword in some compilers ... */ +#endif if (PL_op->op_private & OPpTRANS_SQUASH) { - U8* p = send; UV pch = 0xfeedface; while (s < send) { STRLEN len; - UV comp = utf8_to_uv_simple(s, &len); + UV comp = utf8_to_uvchr(s, &len); - if (comp > 0xff) - d = uv_to_utf8(d, comp); /* always unmapped */ + if (comp > 0xff) { + if (!complement) { + Copy(s, d, len, U8); + d += len; + } + else { + matches++; + if (!del) { + ch = (rlen == 0) ? comp : + (comp - 0x100 < rlen) ? + tbl[comp+1] : tbl[0x100+rlen]; + if (ch != pch) { + d = uvchr_to_utf8(d, ch); + pch = ch; + } + s += len; + continue; + } + } + } else if ((ch = tbl[comp]) >= 0) { matches++; if (ch != pch) { - d = uv_to_utf8(d, ch); + d = uvchr_to_utf8(d, ch); pch = ch; } s += len; continue; } - else if (ch == -1) /* -1 is unmapped character */ - d = uv_to_utf8(d, comp); + else if (ch == -1) { /* -1 is unmapped character */ + Copy(s, d, len, U8); + d += len; + } else if (ch == -2) /* -2 is delete character */ matches++; s += len; @@ -205,23 +248,43 @@ S_do_trans_complex(pTHX_ SV *sv)/* SPC - NOT OK */ else { while (s < send) { STRLEN len; - UV comp = utf8_to_uv_simple(s, &len); - if (comp > 0xff) - d = uv_to_utf8(d, comp); /* always unmapped */ + UV comp = utf8_to_uvchr(s, &len); + if (comp > 0xff) { + if (!complement) { + Copy(s, d, len, U8); + d += len; + } + else { + matches++; + if (!del) { + if (comp - 0x100 < rlen) + d = uvchr_to_utf8(d, tbl[comp+1]); + else + d = uvchr_to_utf8(d, tbl[0x100+rlen]); + } + } + } else if ((ch = tbl[comp]) >= 0) { - d = uv_to_utf8(d, ch); + d = uvchr_to_utf8(d, ch); matches++; } else if (ch == -1) { /* -1 is unmapped character */ - d = uv_to_utf8(d, comp); + Copy(s, d, len, U8); + d += len; } else if (ch == -2) /* -2 is delete character */ matches++; s += len; } } - *d = '\0'; - sv_setpvn(sv, (char*)dstart, d - dstart); + if (grows) { + sv_setpvn(sv, (char*)dstart, d - dstart); + Safefree(dstart); + } + else { + *d = '\0'; + SvCUR_set(sv, d - dstart); + } SvUTF8_on(sv); } SvSETMAGIC(sv); @@ -229,7 +292,7 @@ S_do_trans_complex(pTHX_ SV *sv)/* SPC - NOT OK */ } STATIC I32 -S_do_trans_simple_utf8(pTHX_ SV *sv)/* SPC - OK */ +S_do_trans_simple_utf8(pTHX_ SV *sv) { U8 *s; U8 *send; @@ -237,6 +300,7 @@ S_do_trans_simple_utf8(pTHX_ SV *sv)/* SPC - OK */ U8 *start; U8 *dstart, *dend; I32 matches = 0; + I32 grows = PL_op->op_private & OPpTRANS_GROWS; STRLEN len; SV* rv = (SV*)cSVOP->op_sv; @@ -244,7 +308,7 @@ S_do_trans_simple_utf8(pTHX_ SV *sv)/* SPC - OK */ SV** svp = hv_fetch(hv, "NONE", 4, FALSE); UV none = svp ? SvUV(*svp) : 0x7fffffff; UV extra = none + 1; - UV final; + UV final = 0; UV uv; I32 isutf8; U8 hibit = 0; @@ -253,9 +317,11 @@ S_do_trans_simple_utf8(pTHX_ SV *sv)/* SPC - OK */ isutf8 = SvUTF8(sv); if (!isutf8) { U8 *t = s, *e = s + len; - while (t < e) - if ((hibit = *t++ & 0x80)) + while (t < e) { + U8 ch = *t++; + if ((hibit = !NATIVE_IS_INVARIANT(ch))) break; + } if (hibit) s = bytes_to_utf8(s, &len); } @@ -266,56 +332,69 @@ S_do_trans_simple_utf8(pTHX_ SV *sv)/* SPC - OK */ if (svp) final = SvUV(*svp); - /* d needs to be bigger than s, in case e.g. upgrading is required */ - New(0, d, len*3+UTF8_MAXLEN, U8); - dend = d + len * 3; - dstart = d; + if (grows) { + /* d needs to be bigger than s, in case e.g. upgrading is required */ + New(0, d, len*3+UTF8_MAXLEN, U8); + dend = d + len * 3; + dstart = d; + } + else { + dstart = d = s; + dend = d + len; + } while (s < send) { - if ((uv = swash_fetch(rv, s)) < none) { + if ((uv = swash_fetch(rv, s, TRUE)) < none) { s += UTF8SKIP(s); matches++; - d = uv_to_utf8(d, uv); + d = uvuni_to_utf8(d, uv); } else if (uv == none) { int i = UTF8SKIP(s); - while(i--) - *d++ = *s++; + Copy(s, d, i, U8); + d += i; + s += i; } else if (uv == extra) { int i = UTF8SKIP(s); s += i; matches++; - d = uv_to_utf8(d, final); + d = uvuni_to_utf8(d, final); } else s += UTF8SKIP(s); - if (d >= dend) { + if (d > dend) { STRLEN clen = d - dstart; STRLEN nlen = dend - dstart + len + UTF8_MAXLEN; + if (!grows) + Perl_croak(aTHX_ "panic: do_trans_simple_utf8 line %d",__LINE__); Renew(dstart, nlen+UTF8_MAXLEN, U8); d = dstart + clen; dend = dstart + nlen; } } - *d = '\0'; - sv_setpvn(sv, (char*)dstart, d - dstart); + if (grows || hibit) { + sv_setpvn(sv, (char*)dstart, d - dstart); + Safefree(dstart); + if (grows && hibit) + Safefree(start); + } + else { + *d = '\0'; + SvCUR_set(sv, d - dstart); + } SvSETMAGIC(sv); SvUTF8_on(sv); - if (hibit) - Safefree(start); - if (!isutf8 && !(PL_hints & HINT_UTF8)) - sv_utf8_downgrade(sv, TRUE); return matches; } STATIC I32 -S_do_trans_count_utf8(pTHX_ SV *sv)/* SPC - OK */ +S_do_trans_count_utf8(pTHX_ SV *sv) { U8 *s; - U8 *start, *send; + U8 *start = 0, *send; I32 matches = 0; STRLEN len; @@ -323,22 +402,25 @@ S_do_trans_count_utf8(pTHX_ SV *sv)/* SPC - OK */ HV* hv = (HV*)SvRV(rv); SV** svp = hv_fetch(hv, "NONE", 4, FALSE); UV none = svp ? SvUV(*svp) : 0x7fffffff; + UV extra = none + 1; UV uv; U8 hibit = 0; s = (U8*)SvPV(sv, len); if (!SvUTF8(sv)) { U8 *t = s, *e = s + len; - while (t < e) - if ((hibit = *t++ & 0x80)) + while (t < e) { + U8 ch = *t++; + if ((hibit = !NATIVE_IS_INVARIANT(ch))) break; + } if (hibit) start = s = bytes_to_utf8(s, &len); } send = s + len; while (s < send) { - if ((uv = swash_fetch(rv, s)) < none) + if ((uv = swash_fetch(rv, s, TRUE)) < none || uv == extra) matches++; s += UTF8SKIP(s); } @@ -349,7 +431,7 @@ S_do_trans_count_utf8(pTHX_ SV *sv)/* SPC - OK */ } STATIC I32 -S_do_trans_complex_utf8(pTHX_ SV *sv) /* SPC - NOT OK */ +S_do_trans_complex_utf8(pTHX_ SV *sv) { U8 *s; U8 *start, *send; @@ -357,12 +439,14 @@ S_do_trans_complex_utf8(pTHX_ SV *sv) /* SPC - NOT OK */ I32 matches = 0; I32 squash = PL_op->op_private & OPpTRANS_SQUASH; I32 del = PL_op->op_private & OPpTRANS_DELETE; + I32 grows = PL_op->op_private & OPpTRANS_GROWS; SV* rv = (SV*)cSVOP->op_sv; HV* hv = (HV*)SvRV(rv); SV** svp = hv_fetch(hv, "NONE", 4, FALSE); UV none = svp ? SvUV(*svp) : 0x7fffffff; UV extra = none + 1; - UV final; + UV final = 0; + bool havefinal = FALSE; UV uv; STRLEN len; U8 *dstart, *dend; @@ -373,9 +457,11 @@ S_do_trans_complex_utf8(pTHX_ SV *sv) /* SPC - NOT OK */ isutf8 = SvUTF8(sv); if (!isutf8) { U8 *t = s, *e = s + len; - while (t < e) - if ((hibit = *t++ & 0x80)) + while (t < e) { + U8 ch = *t++; + if ((hibit = !NATIVE_IS_INVARIANT(ch))) break; + } if (hibit) s = bytes_to_utf8(s, &len); } @@ -383,47 +469,72 @@ S_do_trans_complex_utf8(pTHX_ SV *sv) /* SPC - NOT OK */ start = s; svp = hv_fetch(hv, "FINAL", 5, FALSE); - if (svp) + if (svp) { final = SvUV(*svp); + havefinal = TRUE; + } - New(0, d, len*3+UTF8_MAXLEN, U8); - dend = d + len * 3; - dstart = d; + if (grows) { + /* d needs to be bigger than s, in case e.g. upgrading is required */ + New(0, d, len*3+UTF8_MAXLEN, U8); + dend = d + len * 3; + dstart = d; + } + else { + dstart = d = s; + dend = d + len; + } if (squash) { UV puv = 0xfeedface; while (s < send) { - uv = swash_fetch(rv, s); - - if (d >= dend) { - STRLEN clen = d - dstart, nlen = dend - dstart + len; + uv = swash_fetch(rv, s, TRUE); + + if (d > dend) { + STRLEN clen = d - dstart; + STRLEN nlen = dend - dstart + len + UTF8_MAXLEN; + if (!grows) + Perl_croak(aTHX_ "panic: do_trans_complex_utf8 line %d",__LINE__); Renew(dstart, nlen+UTF8_MAXLEN, U8); d = dstart + clen; dend = dstart + nlen; } if (uv < none) { matches++; + s += UTF8SKIP(s); if (uv != puv) { - d = uv_to_utf8(d, uv); + d = uvuni_to_utf8(d, uv); puv = uv; } - s += UTF8SKIP(s); continue; } else if (uv == none) { /* "none" is unmapped character */ int i = UTF8SKIP(s); - while(i--) - *d++ = *s++; + Copy(s, d, i, U8); + d += i; + s += i; puv = 0xfeedface; continue; } else if (uv == extra && !del) { matches++; - if (uv != puv) { - d = uv_to_utf8(d, final); - puv = final; + if (havefinal) { + s += UTF8SKIP(s); + if (puv != final) { + d = uvuni_to_utf8(d, final); + puv = final; + } + } + else { + STRLEN len; + uv = utf8_to_uvuni(s, &len); + if (uv != puv) { + Copy(s, d, len, U8); + d += len; + puv = uv; + } + s += len; } - s += UTF8SKIP(s); continue; } matches++; /* "none+1" is delete character */ @@ -432,42 +543,50 @@ S_do_trans_complex_utf8(pTHX_ SV *sv) /* SPC - NOT OK */ } else { while (s < send) { - uv = swash_fetch(rv, s); - if (d >= dend) { - STRLEN clen = d - dstart, nlen = dend - dstart + len; + uv = swash_fetch(rv, s, TRUE); + if (d > dend) { + STRLEN clen = d - dstart; + STRLEN nlen = dend - dstart + len + UTF8_MAXLEN; + if (!grows) + Perl_croak(aTHX_ "panic: do_trans_complex_utf8 line %d",__LINE__); Renew(dstart, nlen+UTF8_MAXLEN, U8); d = dstart + clen; dend = dstart + nlen; } if (uv < none) { matches++; - d = uv_to_utf8(d, uv); s += UTF8SKIP(s); + d = uvuni_to_utf8(d, uv); continue; } else if (uv == none) { /* "none" is unmapped character */ int i = UTF8SKIP(s); - while(i--) - *d++ = *s++; + Copy(s, d, i, U8); + d += i; + s += i; continue; } else if (uv == extra && !del) { matches++; - d = uv_to_utf8(d, final); s += UTF8SKIP(s); + d = uvuni_to_utf8(d, final); continue; } matches++; /* "none+1" is delete character */ s += UTF8SKIP(s); } } - *d = '\0'; - sv_setpvn(sv, (char*)dstart, d - dstart); + if (grows || hibit) { + sv_setpvn(sv, (char*)dstart, d - dstart); + Safefree(dstart); + if (grows && hibit) + Safefree(start); + } + else { + *d = '\0'; + SvCUR_set(sv, d - dstart); + } SvUTF8_on(sv); - if (hibit) - Safefree(start); - if (!isutf8 && !(PL_hints & HINT_UTF8)) - sv_utf8_downgrade(sv, TRUE); SvSETMAGIC(sv); return matches; @@ -480,9 +599,12 @@ Perl_do_trans(pTHX_ SV *sv) I32 hasutf = (PL_op->op_private & (OPpTRANS_FROM_UTF|OPpTRANS_TO_UTF)); - if (SvREADONLY(sv) && !(PL_op->op_private & OPpTRANS_IDENTICAL)) - Perl_croak(aTHX_ PL_no_modify); - + if (SvREADONLY(sv)) { + if (SvFAKE(sv)) + sv_force_normal(sv); + if (SvREADONLY(sv) && !(PL_op->op_private & OPpTRANS_IDENTICAL)) + Perl_croak(aTHX_ PL_no_modify); + } (void)SvPV(sv, len); if (!len) return 0; @@ -501,6 +623,7 @@ Perl_do_trans(pTHX_ SV *sv) return do_trans_simple(sv); case OPpTRANS_IDENTICAL: + case OPpTRANS_IDENTICAL|OPpTRANS_COMPLEMENT: if (hasutf) return do_trans_count_utf8(sv); else @@ -521,9 +644,11 @@ Perl_do_join(pTHX_ register SV *sv, SV *del, register SV **mark, register SV **s register I32 items = sp - mark; register STRLEN len; STRLEN delimlen; - register char *delim = SvPV(del, delimlen); STRLEN tmplen; + (void) SvPV(del, delimlen); /* stringify and get the delimlen */ + /* SvCUR assumes it's SvPOK() and woe betide you if it's not. */ + mark++; len = (items > 0 ? (delimlen * (items - 1) ) : 0); (void)SvUPGRADE(sv, SVt_PV); @@ -542,14 +667,16 @@ Perl_do_join(pTHX_ register SV *sv, SV *del, register SV **mark, register SV **s ++mark; } + sv_setpv(sv, ""); + if (PL_tainting && SvMAGICAL(sv)) + SvTAINTED_off(sv); + if (items-- > 0) { - sv_setpv(sv, ""); if (*mark) sv_catsv(sv, *mark); mark++; } - else - sv_setpv(sv,""); + if (delimlen) { for (; items > 0; items--,mark++) { sv_catsv(sv,del); @@ -823,8 +950,14 @@ Perl_do_chop(pTHX_ register SV *astr, register SV *sv) do_chop(astr,hv_iterval(hv,entry)); return; } - else if (SvREADONLY(sv)) - Perl_croak(aTHX_ PL_no_modify); + else if (SvREADONLY(sv)) { + if (SvFAKE(sv)) { + /* SV is copy-on-write */ + sv_force_normal_flags(sv, 0); + } + if (SvREADONLY(sv)) + Perl_croak(aTHX_ PL_no_modify); + } s = SvPV(sv, len); if (len && !SvPOK(sv)) s = SvPV_force(sv, len); @@ -835,7 +968,7 @@ Perl_do_chop(pTHX_ register SV *astr, register SV *sv) s = send - 1; while (s > start && UTF8_IS_CONTINUATION(*s)) s--; - if (utf8_to_uv_simple((U8*)s, 0)) { + if (utf8_to_uvchr((U8*)s, 0)) { sv_setpvn(astr, s, send - s); *s = '\0'; SvCUR_set(sv, s - start); @@ -864,6 +997,7 @@ Perl_do_chomp(pTHX_ register SV *sv) { register I32 count; STRLEN len; + STRLEN n_a; char *s; if (RsSNARF(PL_rs)) @@ -892,11 +1026,15 @@ Perl_do_chomp(pTHX_ register SV *sv) count += do_chomp(hv_iterval(hv,entry)); return count; } - else if (SvREADONLY(sv)) - Perl_croak(aTHX_ PL_no_modify); + else if (SvREADONLY(sv)) { + if (SvFAKE(sv)) { + /* SV is copy-on-write */ + sv_force_normal_flags(sv, 0); + } + if (SvREADONLY(sv)) + Perl_croak(aTHX_ PL_no_modify); + } s = SvPV(sv, len); - if (len && !SvPOKp(sv)) - s = SvPV_force(sv, len); if (s && len) { s += --len; if (RsPARA(PL_rs)) { @@ -927,12 +1065,13 @@ Perl_do_chomp(pTHX_ register SV *sv) count += rslen; } } - *s = '\0'; + s = SvPV_force(sv, n_a); SvCUR_set(sv, len); + *SvEND(sv) = '\0'; SvNIOK_off(sv); + SvSETMAGIC(sv); } nope: - SvSETMAGIC(sv); return count; } @@ -955,7 +1094,7 @@ Perl_do_vop(pTHX_ I32 optype, SV *sv, SV *left, SV *right) char *rsave; bool left_utf = DO_UTF8(left); bool right_utf = DO_UTF8(right); - I32 needlen; + I32 needlen = 0; if (left_utf && !right_utf) sv_utf8_upgrade(right); @@ -1001,14 +1140,14 @@ Perl_do_vop(pTHX_ I32 optype, SV *sv, SV *left, SV *right) switch (optype) { case OP_BIT_AND: while (lulen && rulen) { - luc = utf8_to_uv((U8*)lc, lulen, &ulen, UTF8_ALLOW_ANYUV); + luc = utf8n_to_uvchr((U8*)lc, lulen, &ulen, UTF8_ALLOW_ANYUV); lc += ulen; lulen -= ulen; - ruc = utf8_to_uv((U8*)rc, rulen, &ulen, UTF8_ALLOW_ANYUV); + ruc = utf8n_to_uvchr((U8*)rc, rulen, &ulen, UTF8_ALLOW_ANYUV); rc += ulen; rulen -= ulen; duc = luc & ruc; - dc = (char*)uv_to_utf8((U8*)dc, duc); + dc = (char*)uvchr_to_utf8((U8*)dc, duc); } if (sv == left || sv == right) (void)sv_usepvn(sv, dcsave, needlen); @@ -1016,26 +1155,26 @@ Perl_do_vop(pTHX_ I32 optype, SV *sv, SV *left, SV *right) break; case OP_BIT_XOR: while (lulen && rulen) { - luc = utf8_to_uv((U8*)lc, lulen, &ulen, UTF8_ALLOW_ANYUV); + luc = utf8n_to_uvchr((U8*)lc, lulen, &ulen, UTF8_ALLOW_ANYUV); lc += ulen; lulen -= ulen; - ruc = utf8_to_uv((U8*)rc, rulen, &ulen, UTF8_ALLOW_ANYUV); + ruc = utf8n_to_uvchr((U8*)rc, rulen, &ulen, UTF8_ALLOW_ANYUV); rc += ulen; rulen -= ulen; duc = luc ^ ruc; - dc = (char*)uv_to_utf8((U8*)dc, duc); + dc = (char*)uvchr_to_utf8((U8*)dc, duc); } goto mop_up_utf; case OP_BIT_OR: while (lulen && rulen) { - luc = utf8_to_uv((U8*)lc, lulen, &ulen, UTF8_ALLOW_ANYUV); + luc = utf8n_to_uvchr((U8*)lc, lulen, &ulen, UTF8_ALLOW_ANYUV); lc += ulen; lulen -= ulen; - ruc = utf8_to_uv((U8*)rc, rulen, &ulen, UTF8_ALLOW_ANYUV); + ruc = utf8n_to_uvchr((U8*)rc, rulen, &ulen, UTF8_ALLOW_ANYUV); rc += ulen; rulen -= ulen; duc = luc | ruc; - dc = (char*)uv_to_utf8((U8*)dc, duc); + dc = (char*)uvchr_to_utf8((U8*)dc, duc); } mop_up_utf: if (sv == left || sv == right) @@ -1130,7 +1269,7 @@ finish: OP * Perl_do_kv(pTHX) { - djSP; + dSP; HV *hv = (HV*)POPs; HV *keys; register HE *entry; @@ -1144,7 +1283,7 @@ Perl_do_kv(pTHX) dokeys = dovalues = TRUE; if (!hv) { - if (PL_op->op_flags & OPf_MOD) { /* lvalue */ + if (PL_op->op_flags & OPf_MOD || LVRET) { /* lvalue */ dTARGET; /* make sure to clear its target here */ if (SvTYPE(TARG) == SVt_PVLV) LvTARG(TARG) = Nullsv; @@ -1163,10 +1302,10 @@ Perl_do_kv(pTHX) IV i; dTARGET; - if (PL_op->op_flags & OPf_MOD) { /* lvalue */ + if (PL_op->op_flags & OPf_MOD || LVRET) { /* lvalue */ if (SvTYPE(TARG) < SVt_PVLV) { sv_upgrade(TARG, SVt_PVLV); - sv_magic(TARG, Nullsv, 'k', Nullch, 0); + sv_magic(TARG, Nullsv, PERL_MAGIC_nkeys, Nullch, 0); } LvTYPE(TARG) = 'k'; if (LvTARG(TARG) != (SV*)keys) { @@ -1178,7 +1317,7 @@ Perl_do_kv(pTHX) RETURN; } - if (! SvTIED_mg((SV*)keys, 'P')) + if (! SvTIED_mg((SV*)keys, PERL_MAGIC_tied)) i = HvKEYS(keys); else { i = 0;