Changes to perlfaq8 "How do I find out if I'm running interactively
[p5sagit/p5-mst-13.2.git] / doop.c
diff --git a/doop.c b/doop.c
index 0e9ddf1..c4edb60 100644 (file)
--- a/doop.c
+++ b/doop.c
@@ -69,7 +69,7 @@ S_do_trans_simple(pTHX_ SV *sv)
        I32 ch;
 
         /* Need to check this, otherwise 128..255 won't match */
-       const UV c = utf8n_to_uvchr(s, send - s, &ulen, 0);
+       const UV c = utf8n_to_uvchr(s, send - s, &ulen, UTF8_ALLOW_DEFAULT);
         if (c < 0x100 && (ch = tbl[c]) >= 0) {
             matches++;
            d = uvchr_to_utf8(d, ch);
@@ -119,7 +119,7 @@ S_do_trans_count(pTHX_ SV *sv)
        const I32 complement = PL_op->op_private & OPpTRANS_COMPLEMENT;
        while (s < send) {
            STRLEN ulen;
-           const UV c = utf8n_to_uvchr(s, send - s, &ulen, 0);
+           const UV c = utf8n_to_uvchr(s, send - s, &ulen, UTF8_ALLOW_DEFAULT);
            if (c < 0x100) {
                if (tbl[c] >= 0)
                    matches++;
@@ -209,12 +209,13 @@ S_do_trans_complex(pTHX_ SV *sv)
            UV pch = 0xfeedface;
            while (s < send) {
                STRLEN len;
-               const UV comp = utf8_to_uvchr(s, &len);
+               const UV comp = utf8n_to_uvchr(s, send - s, &len,
+                                              UTF8_ALLOW_DEFAULT);
                I32 ch;
 
                if (comp > 0xff) {
                    if (!complement) {
-                       Copy(s, d, len, U8);
+                       Move(s, d, len, U8);
                        d += len;
                    }
                    else {
@@ -242,7 +243,7 @@ S_do_trans_complex(pTHX_ SV *sv)
                    continue;
                }
                else if (ch == -1) {    /* -1 is unmapped character */
-                   Copy(s, d, len, U8);
+                   Move(s, d, len, U8);
                    d += len;
                }
                else if (ch == -2)      /* -2 is delete character */
@@ -254,7 +255,8 @@ S_do_trans_complex(pTHX_ SV *sv)
        else {
            while (s < send) {
                STRLEN len;
-               const UV comp = utf8_to_uvchr(s, &len);
+               const UV comp = utf8n_to_uvchr(s, send - s, &len,
+                                              UTF8_ALLOW_DEFAULT);
                I32 ch;
                if (comp > 0xff) {
                    if (!complement) {
@@ -276,7 +278,7 @@ S_do_trans_complex(pTHX_ SV *sv)
                    matches++;
                }
                else if (ch == -1) {    /* -1 is unmapped character */
-                   Copy(s, d, len, U8);
+                   Move(s, d, len, U8);
                    d += len;
                }
                else if (ch == -2)      /* -2 is delete character */
@@ -540,7 +542,7 @@ S_do_trans_complex_utf8(pTHX_ SV *sv)
                }
                else {
                    STRLEN len;
-                   uv = utf8_to_uvuni(s, &len);
+                   uv = utf8n_to_uvuni(s, send - s, &len, UTF8_ALLOW_DEFAULT);
                    if (uv != puv) {
                        Move(s, d, len, U8);
                        d += len;
@@ -1195,6 +1197,8 @@ Perl_do_vop(pTHX_ I32 optype, SV *sv, SV *left, SV *right)
     rsave = rc = SvPV_nomg_const(right, rightlen);
     len = leftlen < rightlen ? leftlen : rightlen;
     lensave = len;
+    SvCUR_set(sv, len);
+    (void)SvPOK_only(sv);
     if ((left_utf || right_utf) && (sv == left || sv == right)) {
        needlen = optype == OP_BIT_AND ? len : leftlen + rightlen;
        Newxz(dc, needlen + 1, char);
@@ -1212,14 +1216,13 @@ Perl_do_vop(pTHX_ I32 optype, SV *sv, SV *left, SV *right)
        needlen = ((optype == OP_BIT_AND)
                    ? len : (leftlen > rightlen ? leftlen : rightlen));
        Newxz(dc, needlen + 1, char);
-       (void)sv_usepvn(sv, dc, needlen);
+       sv_usepvn_flags(sv, dc, needlen, SV_HAS_TRAILING_NUL);
        dc = SvPVX(sv);         /* sv_usepvn() calls Renew() */
     }
-    SvCUR_set(sv, len);
-    (void)SvPOK_only(sv);
     if (left_utf || right_utf) {
        UV duc, luc, ruc;
-       char * const dcsave = dc;
+       char *dcorig = dc;
+       char *dcsave = NULL;
        STRLEN lulen = leftlen;
        STRLEN rulen = rightlen;
        STRLEN ulen;
@@ -1237,8 +1240,8 @@ Perl_do_vop(pTHX_ I32 optype, SV *sv, SV *left, SV *right)
                dc = (char*)uvchr_to_utf8((U8*)dc, duc);
            }
            if (sv == left || sv == right)
-               (void)sv_usepvn(sv, dcsave, needlen);
-           SvCUR_set(sv, dc - dcsave);
+               (void)sv_usepvn(sv, dcorig, needlen);
+           SvCUR_set(sv, dc - dcorig);
            break;
        case OP_BIT_XOR:
            while (lulen && rulen) {
@@ -1264,16 +1267,26 @@ Perl_do_vop(pTHX_ I32 optype, SV *sv, SV *left, SV *right)
                dc = (char*)uvchr_to_utf8((U8*)dc, duc);
            }
          mop_up_utf:
+           if (rulen)
+               dcsave = savepvn(rc, rulen);
+           else if (lulen)
+               dcsave = savepvn(lc, lulen);
            if (sv == left || sv == right)
-               (void)sv_usepvn(sv, dcsave, needlen);
-           SvCUR_set(sv, dc - dcsave);
+               (void)sv_usepvn(sv, dcorig, needlen); /* Uses Renew(). */
+           SvCUR_set(sv, dc - dcorig);
            if (rulen)
-               sv_catpvn(sv, rc, rulen);
+               sv_catpvn(sv, dcsave, rulen);
            else if (lulen)
-               sv_catpvn(sv, lc, lulen);
+               sv_catpvn(sv, dcsave, lulen);
            else
                *SvEND(sv) = '\0';
+           Safefree(dcsave);
            break;
+       default:
+           if (sv == left || sv == right)
+               Safefree(dcorig);
+           Perl_croak(aTHX_ "panic: do_vop called for op %u (%s)", optype,
+                      PL_op_name[optype]);
        }
        SvUTF8_on(sv);
        goto finish;
@@ -1396,7 +1409,7 @@ Perl_do_kv(pTHX)
            if (LvTARG(TARG) != (SV*)keys) {
                if (LvTARG(TARG))
                    SvREFCNT_dec(LvTARG(TARG));
-               LvTARG(TARG) = SvREFCNT_inc(keys);
+               LvTARG(TARG) = SvREFCNT_inc_simple(keys);
            }
            PUSHs(TARG);
            RETURN;