Stop tr/// from writing to target when only counting.
Malcolm Beattie [Thu, 11 Dec 1997 11:54:41 +0000 (11:54 +0000)]
p4raw-id: //depot/perl@359

doop.c
op.c
op.h

diff --git a/doop.c b/doop.c
index 277f46e..be3e674 100644 (file)
--- a/doop.c
+++ b/doop.c
@@ -31,7 +31,7 @@ do_trans(SV *sv, OP *arg)
     register I32 squash = op->op_private & OPpTRANS_SQUASH;
     STRLEN len;
 
-    if (SvREADONLY(sv))
+    if (SvREADONLY(sv) && !(op->op_private & OPpTRANS_COUNTONLY))
        croak(no_modify);
     tbl = (short*)cPVOP->op_pv;
     s = (U8*)SvPV(sv, len);
@@ -52,6 +52,14 @@ do_trans(SV *sv, OP *arg)
            }
            s++;
        }
+       SvSETMAGIC(sv);
+    }
+    else if (op->op_private & OPpTRANS_COUNTONLY) {
+       while (s < send) {
+           if (tbl[*s] >= 0)
+               matches++;
+           s++;
+       }
     }
     else {
        d = s;
@@ -74,8 +82,8 @@ do_trans(SV *sv, OP *arg)
        matches += send - d;    /* account for disappeared chars */
        *d = '\0';
        SvCUR_set(sv, d - (U8*)SvPVX(sv));
+       SvSETMAGIC(sv);
     }
-    SvSETMAGIC(sv);
     return matches;
 }
 
diff --git a/op.c b/op.c
index a922a2b..c6e1cfe 100644 (file)
--- a/op.c
+++ b/op.c
@@ -1993,12 +1993,13 @@ pmtrans(OP *o, OP *expr, OP *repl)
     register I32 j;
     I32 Delete;
     I32 complement;
+    I32 squash;
     register short *tbl;
 
     tbl = (short*)cPVOPo->op_pv;
     complement = o->op_private & OPpTRANS_COMPLEMENT;
     Delete     = o->op_private & OPpTRANS_DELETE;
-    /* squash  = o->op_private & OPpTRANS_SQUASH; */
+    squash     = o->op_private & OPpTRANS_SQUASH;
 
     if (complement) {
        Zero(tbl, 256, short);
@@ -2022,6 +2023,8 @@ pmtrans(OP *o, OP *expr, OP *repl)
     else {
        if (!rlen && !Delete) {
            r = t; rlen = tlen;
+           if (!squash)
+               o->op_private |= OPpTRANS_COUNTONLY;
        }
        for (i = 0; i < 256; i++)
            tbl[i] = -1;
diff --git a/op.h b/op.h
index 471ace0..a203c44 100644 (file)
--- a/op.h
+++ b/op.h
@@ -95,6 +95,7 @@ typedef U32 PADOFFSET;
 #define OPpRUNTIME             64      /* Pattern coming in on the stack */
 
 /* Private for OP_TRANS */
+#define OPpTRANS_COUNTONLY     8
 #define OPpTRANS_SQUASH                16
 #define OPpTRANS_DELETE                32
 #define OPpTRANS_COMPLEMENT    64