X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pp.c;h=1c323f783d1cb7a703e0df2914d691aa2f71c265;hb=9459710475e45fb4a97fce8a8bc59383952cc617;hp=eca00c8ec296d326ddcb4bae09802b4369acfa61;hpb=39b99f2105ed8866b81c468bff75857b0c5187f9;p=p5sagit%2Fp5-mst-13.2.git diff --git a/pp.c b/pp.c index eca00c8..1c323f7 100644 --- a/pp.c +++ b/pp.c @@ -1074,9 +1074,13 @@ PP(pp_divide) #else /* Otherwise we only attempt it if either or both operands would not be preserved by an NV. If both fit in NVs - we fall through to the NV divide code below. */ - && ((left > ((UV)1 << NV_PRESERVES_UV_BITS)) - || (right > ((UV)1 << NV_PRESERVES_UV_BITS))) + we fall through to the NV divide code below. However, + as left >= right to ensure integer result here, we know that + we can skip the test on the right operand - right big + enough not to be preserved can't get here unless left is + also too big. */ + + && (left > ((UV)1 << NV_PRESERVES_UV_BITS)) #endif ) { /* Integer division can't overflow, but it can be imprecise. */ @@ -1494,11 +1498,6 @@ PP(pp_lt) RETURN; } auv = SvUVX(TOPs); - if (auv >= (UV) IV_MAX) { - /* As (b) is an IV, it cannot be > IV_MAX */ - SETs(&PL_sv_no); - RETURN; - } SETs(boolSV(auv < (UV)biv)); RETURN; } @@ -1515,11 +1514,6 @@ PP(pp_lt) } buv = SvUVX(TOPs); SP--; - if (buv > (UV) IV_MAX) { - /* As (a) is an IV, it cannot be > IV_MAX */ - SETs(&PL_sv_yes); - RETURN; - } SETs(boolSV((UV)aiv < buv)); RETURN; } @@ -1572,11 +1566,6 @@ PP(pp_gt) RETURN; } auv = SvUVX(TOPs); - if (auv > (UV) IV_MAX) { - /* As (b) is an IV, it cannot be > IV_MAX */ - SETs(&PL_sv_yes); - RETURN; - } SETs(boolSV(auv > (UV)biv)); RETURN; } @@ -1593,11 +1582,6 @@ PP(pp_gt) } buv = SvUVX(TOPs); SP--; - if (buv >= (UV) IV_MAX) { - /* As (a) is an IV, it cannot be > IV_MAX */ - SETs(&PL_sv_no); - RETURN; - } SETs(boolSV((UV)aiv > buv)); RETURN; } @@ -1650,11 +1634,6 @@ PP(pp_le) RETURN; } auv = SvUVX(TOPs); - if (auv > (UV) IV_MAX) { - /* As (b) is an IV, it cannot be > IV_MAX */ - SETs(&PL_sv_no); - RETURN; - } SETs(boolSV(auv <= (UV)biv)); RETURN; } @@ -1671,11 +1650,6 @@ PP(pp_le) } buv = SvUVX(TOPs); SP--; - if (buv >= (UV) IV_MAX) { - /* As (a) is an IV, it cannot be > IV_MAX */ - SETs(&PL_sv_yes); - RETURN; - } SETs(boolSV((UV)aiv <= buv)); RETURN; } @@ -1728,11 +1702,6 @@ PP(pp_ge) RETURN; } auv = SvUVX(TOPs); - if (auv >= (UV) IV_MAX) { - /* As (b) is an IV, it cannot be > IV_MAX */ - SETs(&PL_sv_yes); - RETURN; - } SETs(boolSV(auv >= (UV)biv)); RETURN; } @@ -1749,11 +1718,6 @@ PP(pp_ge) } buv = SvUVX(TOPs); SP--; - if (buv > (UV) IV_MAX) { - /* As (a) is an IV, it cannot be > IV_MAX */ - SETs(&PL_sv_no); - RETURN; - } SETs(boolSV((UV)aiv >= buv)); RETURN; } @@ -1825,11 +1789,6 @@ PP(pp_ne) } uv = SvUVX(*(SP+1)); /* Do I want TOPp1s() ? */ } - /* we know iv is >= 0 */ - if (uv > (UV) IV_MAX) { - SETs(&PL_sv_yes); - RETURN; - } SETs(boolSV((UV)iv != uv)); RETURN; } @@ -1891,10 +1850,7 @@ PP(pp_ncmp) value = 1; } else { leftuv = SvUVX(TOPm1s); - if (leftuv > (UV) IV_MAX) { - /* As (b) is an IV, it cannot be > IV_MAX */ - value = 1; - } else if (leftuv > (UV)rightiv) { + if (leftuv > (UV)rightiv) { value = 1; } else if (leftuv < (UV)rightiv) { value = -1; @@ -1912,12 +1868,9 @@ PP(pp_ncmp) value = -1; } else { rightuv = SvUVX(TOPs); - if (rightuv > (UV) IV_MAX) { - /* As (a) is an IV, it cannot be > IV_MAX */ - value = -1; - } else if (leftiv > (UV)rightuv) { + if ((UV)leftiv > rightuv) { value = 1; - } else if (leftiv < (UV)rightuv) { + } else if ((UV)leftiv < rightuv) { value = -1; } else { value = 0; @@ -2157,15 +2110,22 @@ PP(pp_negate) sv_setsv(TARG, sv); *SvPV_force(TARG, len) = *s == '-' ? '+' : '-'; } - else if (DO_UTF8(sv) && UTF8_IS_START(*s) && isIDFIRST_utf8((U8*)s)) { - sv_setpvn(TARG, "-", 1); - sv_catsv(TARG, sv); + else if (DO_UTF8(sv)) { + SvIV_please(sv); + if (SvIOK(sv)) + goto oops_its_an_int; + if (SvNOK(sv)) + sv_setnv(TARG, -SvNV(sv)); + else { + sv_setpvn(TARG, "-", 1); + sv_catsv(TARG, sv); + } } else { - SvIV_please(sv); - if (SvIOK(sv)) - goto oops_its_an_int; - sv_setnv(TARG, -SvNV(sv)); + SvIV_please(sv); + if (SvIOK(sv)) + goto oops_its_an_int; + sv_setnv(TARG, -SvNV(sv)); } SETTARG; } @@ -3149,34 +3109,27 @@ PP(pp_ucfirst) register U8 *s; STRLEN slen; - if (DO_UTF8(sv) && (s = (U8*)SvPV(sv, slen)) && slen && UTF8_IS_START(*s)) { + if (DO_UTF8(sv)) { + U8 tmpbuf[UTF8_MAXLEN*2+1]; STRLEN ulen; - U8 tmpbuf[UTF8_MAXLEN+1]; - U8 *tend; - UV uv; + STRLEN tculen; - if (IN_LOCALE_RUNTIME) { - TAINT; - SvTAINTED_on(sv); - uv = toTITLE_LC_uvchr(utf8n_to_uvchr(s, slen, &ulen, 0)); - } - else { - uv = toTITLE_utf8(s); - ulen = UNISKIP(uv); - } - - tend = uvchr_to_utf8(tmpbuf, uv); + s = (U8*)SvPV(sv, slen); + utf8_to_uvchr(s, &ulen); - if (!SvPADTMP(sv) || tend - tmpbuf != ulen || SvREADONLY(sv)) { + toTITLE_utf8(s, tmpbuf, &tculen); + utf8_to_uvchr(tmpbuf, 0); + + if (!SvPADTMP(sv) || SvREADONLY(sv)) { dTARGET; - sv_setpvn(TARG, (char*)tmpbuf, tend - tmpbuf); + sv_setpvn(TARG, (char*)tmpbuf, tculen); sv_catpvn(TARG, (char*)(s + ulen), slen - ulen); SvUTF8_on(TARG); SETs(TARG); } else { s = (U8*)SvPV_force(sv, slen); - Copy(tmpbuf, s, ulen, U8); + Copy(tmpbuf, s, tculen, U8); } } else { @@ -3212,19 +3165,12 @@ PP(pp_lcfirst) if (DO_UTF8(sv) && (s = (U8*)SvPV(sv, slen)) && slen && UTF8_IS_START(*s)) { STRLEN ulen; - U8 tmpbuf[UTF8_MAXLEN+1]; + U8 tmpbuf[UTF8_MAXLEN*2+1]; U8 *tend; UV uv; - if (IN_LOCALE_RUNTIME) { - TAINT; - SvTAINTED_on(sv); - uv = toLOWER_LC_uvchr(utf8n_to_uvchr(s, slen, &ulen, 0)); - } - else { - uv = toLOWER_utf8(s); - ulen = UNISKIP(uv); - } + toLOWER_utf8(s, tmpbuf, &ulen); + uv = utf8_to_uvchr(tmpbuf, 0); tend = uvchr_to_utf8(tmpbuf, uv); @@ -3276,6 +3222,7 @@ PP(pp_uc) STRLEN ulen; register U8 *d; U8 *send; + U8 tmpbuf[UTF8_MAXLEN*2+1]; s = (U8*)SvPV(sv,len); if (!len) { @@ -3289,19 +3236,11 @@ PP(pp_uc) (void)SvPOK_only(TARG); d = (U8*)SvPVX(TARG); send = s + len; - if (IN_LOCALE_RUNTIME) { - TAINT; - SvTAINTED_on(TARG); - while (s < send) { - d = uvchr_to_utf8(d, toUPPER_LC_uvchr( utf8n_to_uvchr(s, len, &ulen, 0))); - s += ulen; - } - } - else { - while (s < send) { - d = uvchr_to_utf8(d, toUPPER_utf8( s )); - s += UTF8SKIP(s); - } + while (s < send) { + toUPPER_utf8(s, tmpbuf, &ulen); + Copy(tmpbuf, d, ulen, U8); + d += ulen; + s += UTF8SKIP(s); } *d = '\0'; SvUTF8_on(TARG); @@ -3350,6 +3289,7 @@ PP(pp_lc) STRLEN ulen; register U8 *d; U8 *send; + U8 tmpbuf[UTF8_MAXLEN*2+1]; s = (U8*)SvPV(sv,len); if (!len) { @@ -3363,19 +3303,28 @@ PP(pp_lc) (void)SvPOK_only(TARG); d = (U8*)SvPVX(TARG); send = s + len; - if (IN_LOCALE_RUNTIME) { - TAINT; - SvTAINTED_on(TARG); - while (s < send) { - d = uvchr_to_utf8(d, toLOWER_LC_uvchr( utf8n_to_uvchr(s, len, &ulen, 0))); - s += ulen; - } - } - else { - while (s < send) { - d = uvchr_to_utf8(d, toLOWER_utf8(s)); - s += UTF8SKIP(s); + while (s < send) { + UV uv = toLOWER_utf8(s, tmpbuf, &ulen); +#define GREEK_CAPITAL_LETTER_SIGMA 0x03A3 /* Unicode */ + if (uv == GREEK_CAPITAL_LETTER_SIGMA) { + /* + * Now if the sigma is NOT followed by + * /$ignorable_sequence$cased_letter/; + * and it IS preceded by + * /$cased_letter$ignorable_sequence/; + * where $ignorable_sequence is + * [\x{2010}\x{AD}\p{Mn}]* + * and $cased_letter is + * [\p{Ll}\p{Lo}\p{Lt}] + * then it should be mapped to 0x03C2, + * (GREEK SMALL LETTER FINAL SIGMA), + * instead of staying 0x03A3. + * See lib/unicore/SpecCase.txt. + */ } + Copy(tmpbuf, d, ulen, U8); + d += ulen; + s += UTF8SKIP(s); } *d = '\0'; SvUTF8_on(TARG);