X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=doop.c;h=11dc837b33dc7240d0a40719c6cca8879841d5e4;hb=7b8d334a971230040a212bc5038097b3f600a094;hp=93b618ce5b1733d910453968a8ec7f70c3f9cf22;hpb=af702f0e61214b54e323d12ffeaff4e64bee707c;p=p5sagit%2Fp5-mst-13.2.git diff --git a/doop.c b/doop.c index 93b618c..11dc837 100644 --- a/doop.c +++ b/doop.c @@ -29,9 +29,10 @@ do_trans(SV *sv, OP *arg) register I32 ch; register I32 matches = 0; register I32 squash = op->op_private & OPpTRANS_SQUASH; + register U8 *p; 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,17 +53,27 @@ 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; + p = send; while (s < send) { if ((ch = tbl[*s]) >= 0) { *d = ch; - if (matches++ && squash) { - if (d[-1] == *d) + matches++; + if (squash) { + if (p == d - 1 && *p == *d) matches--; else - d++; + p = d++; } else d++; @@ -74,8 +85,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; } @@ -432,7 +443,7 @@ do_vop(I32 optype, SV *sv, SV *left, SV *right) OP * do_kv(ARGSproto) { - dSP; + djSP; HV *hv = (HV*)POPs; register HE *entry; SV *tmpstr; @@ -463,7 +474,7 @@ do_kv(ARGSproto) RETURN; if (gimme == G_SCALAR) { - I32 i; + IV i; dTARGET; if (op->op_flags & OPf_MOD) { /* lvalue */ @@ -491,7 +502,7 @@ do_kv(ARGSproto) } /* Guess how much room we need. hv_max may be a few too many. Oh well. */ - EXTEND(sp, HvMAX(hv) * (dokeys + dovalues)); + EXTEND(SP, HvMAX(hv) * (dokeys + dovalues)); PUTBACK; /* hv_iternext and hv_iterval might clobber stack_sp */ while (entry = realhv ? hv_iternext(hv) : avhv_iternext((AV*)hv)) { @@ -514,3 +525,4 @@ do_kv(ARGSproto) } return NORMAL; } +