Confusion over uselargefiles.cbu and uselfs.cbu (the first one
[p5sagit/p5-mst-13.2.git] / doop.c
diff --git a/doop.c b/doop.c
index 990898d..4f536f0 100644 (file)
--- a/doop.c
+++ b/doop.c
@@ -1,6 +1,6 @@
 /*    doop.c
  *
- *    Copyright (c) 1991-1999, Larry Wall
+ *    Copyright (c) 1991-2000, Larry Wall
  *
  *    You may distribute under the terms of either the GNU General Public
  *    License or the Artistic License, as specified in the README file.
@@ -282,7 +282,7 @@ S_do_trans_CU_simple(pTHX_ SV *sv)
     UV extra = none + 1;
     UV final;
     UV uv;
-    U8 tmpbuf[10];
+    U8 tmpbuf[UTF8_MAXLEN];
     I32 bits = 16;
 
     s = (U8*)SvPV(sv, len);
@@ -933,7 +933,7 @@ Perl_do_chop(pTHX_ register SV *astr, register SV *sv)
     s = SvPV(sv, len);
     if (len && !SvPOK(sv))
        s = SvPV_force(sv, len);
-    if (IN_UTF8) {
+    if (DO_UTF8(sv)) {
        if (s && len) {
            char *send = s + len;
            char *start = s;
@@ -946,22 +946,23 @@ Perl_do_chop(pTHX_ register SV *astr, register SV *sv)
            *s = '\0';
            SvCUR_set(sv, s - start);
            SvNIOK_off(sv);
+           SvUTF8_on(astr);
        }
        else
            sv_setpvn(astr, "", 0);
     }
-    else
-    if (s && len) {
+    else if (s && len) {
        s += --len;
        sv_setpvn(astr, s, 1);
        *s = '\0';
        SvCUR_set(sv, len);
+       SvUTF8_off(sv);
        SvNIOK_off(sv);
     }
     else
        sv_setpvn(astr, "", 0);
     SvSETMAGIC(sv);
-} 
+}
 
 I32
 Perl_do_chomp(pTHX_ register SV *sv)
@@ -1059,6 +1060,13 @@ Perl_do_vop(pTHX_ I32 optype, SV *sv, SV *left, SV *right)
     I32 lensave;
     char *lsave;
     char *rsave;
+    bool left_utf = DO_UTF8(left);
+    bool right_utf = DO_UTF8(right);
+
+    if (left_utf && !right_utf)
+       sv_utf8_upgrade(right);
+    if (!left_utf && right_utf)
+       sv_utf8_upgrade(left);
 
     if (sv != left || (optype != OP_BIT_AND && !SvOK(sv) && !SvGMAGICAL(sv)))
        sv_setpvn(sv, "", 0);   /* avoid undef warning on |= and ^= */
@@ -1083,6 +1091,66 @@ Perl_do_vop(pTHX_ I32 optype, SV *sv, SV *left, SV *right)
     }
     SvCUR_set(sv, len);
     (void)SvPOK_only(sv);
+    if (left_utf || right_utf) {
+       UV duc, luc, ruc;
+       STRLEN lulen = leftlen;
+       STRLEN rulen = rightlen;
+       STRLEN dulen = 0;
+       I32 ulen;
+
+       switch (optype) {
+       case OP_BIT_AND:
+           while (lulen && rulen) {
+               luc = utf8_to_uv((U8*)lc, &ulen);
+               lc += ulen;
+               lulen -= ulen;
+               ruc = utf8_to_uv((U8*)rc, &ulen);
+               rc += ulen;
+               rulen -= ulen;
+               duc = luc & ruc;
+               dc = (char*)uv_to_utf8((U8*)dc, duc);
+           }
+           dulen = dc - SvPVX(sv);
+           SvCUR_set(sv, dulen);
+           break;
+       case OP_BIT_XOR:
+           while (lulen && rulen) {
+               luc = utf8_to_uv((U8*)lc, &ulen);
+               lc += ulen;
+               lulen -= ulen;
+               ruc = utf8_to_uv((U8*)rc, &ulen);
+               rc += ulen;
+               rulen -= ulen;
+               duc = luc ^ ruc;
+               dc = (char*)uv_to_utf8((U8*)dc, duc);
+           }
+           goto mop_up_utf;
+       case OP_BIT_OR:
+           while (lulen && rulen) {
+               luc = utf8_to_uv((U8*)lc, &ulen);
+               lc += ulen;
+               lulen -= ulen;
+               ruc = utf8_to_uv((U8*)rc, &ulen);
+               rc += ulen;
+               rulen -= ulen;
+               duc = luc | ruc;
+               dc = (char*)uv_to_utf8((U8*)dc, duc);
+           }
+         mop_up_utf:
+           dulen = dc - SvPVX(sv);
+           SvCUR_set(sv, dulen);
+           if (rulen)
+               sv_catpvn(sv, rc, rulen);
+           else if (lulen)
+               sv_catpvn(sv, lc, lulen);
+           else
+               *SvEND(sv) = '\0';
+           break;
+       }
+       SvUTF8_on(sv);
+       goto finish;
+    }
+    else
 #ifdef LIBERAL
     if (len >= sizeof(long)*4 &&
        !((long)dc % sizeof(long)) &&
@@ -1153,6 +1221,7 @@ Perl_do_vop(pTHX_ I32 optype, SV *sv, SV *left, SV *right)
            break;
        }
     }
+finish:
     SvTAINT(sv);
 }