X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=doop.c;h=9dc9b047b4e436542b53420e6705219b55ea67d0;hb=a176fa2a176313dc1a9b9594d080f47292ff4070;hp=5b76367305055be54292bc5238e0212317ee8d66;hpb=11343788cbaaede18e3146b5219d2fbdaeaf516e;p=p5sagit%2Fp5-mst-13.2.git diff --git a/doop.c b/doop.c index 5b76367..9dc9b04 100644 --- a/doop.c +++ b/doop.c @@ -1,6 +1,6 @@ /* doop.c * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, 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. @@ -18,83 +18,328 @@ #include #endif -#ifdef BUGGY_MSC - #pragma function(memcmp) -#endif /* BUGGY_MSC */ - -#ifdef BUGGY_MSC - #pragma intrinsic(memcmp) -#endif /* BUGGY_MSC */ - I32 -do_trans(sv,arg) -SV *sv; -OP *arg; +do_trans(SV *sv, OP *arg) { dTHR; - register short *tbl; register U8 *s; register U8 *send; register U8 *d; - register I32 ch; register I32 matches = 0; - register I32 squash = op->op_private & OPpTRANS_SQUASH; + register I32 squash = PL_op->op_private & OPpTRANS_SQUASH; STRLEN len; - if (SvREADONLY(sv)) + if (SvREADONLY(sv) && !(PL_op->op_private & OPpTRANS_COUNTONLY)) croak(no_modify); - tbl = (short*)cPVOP->op_pv; - s = (U8*)SvPV(sv, len); - if (!len) - return 0; - if (!SvPOKp(sv)) - s = (U8*)SvPV_force(sv, len); - (void)SvPOK_only(sv); - send = s + len; - if (!tbl || !s) - croak("panic: do_trans"); - DEBUG_t( deb("2.TBL\n")); - if (!op->op_private) { - while (s < send) { - if ((ch = tbl[*s]) >= 0) { - matches++; - *s = ch; + + if (PL_op->op_private & (OPpTRANS_FROM_UTF|OPpTRANS_TO_UTF)) { + SV* rv = (SV*)cSVOP->op_sv; + HV* hv = (HV*)SvRV(rv); + SV** svp = hv_fetch(hv, "NONE", 4, FALSE); + UV none = svp ? SvUV(*svp) : 0x7fffffff; + UV extra = none + 1; + I32 del = PL_op->op_private & OPpTRANS_DELETE; + UV final; + register UV uv; + UV puv; + char *dst; + register I32 from_utf = PL_op->op_private & OPpTRANS_FROM_UTF; + register I32 to_utf = PL_op->op_private & OPpTRANS_TO_UTF; + + s = (U8*)SvPV(sv, len); + if (!len) + return 0; + if (!SvPOKp(sv)) + s = (U8*)SvPV_force(sv, len); + (void)SvPOK_only(sv); + send = s + len; + DEBUG_t( deb("2.TBL\n")); + if (PL_op->op_private == (OPpTRANS_FROM_UTF|OPpTRANS_TO_UTF)) { /* no other flags */ + svp = hv_fetch(hv, "FINAL", 5, FALSE); + if (svp) + final = SvUV(*svp); + + d = s; + while (s < send) { + if ((uv = swash_fetch(rv, s)) < none) { + s += UTF8SKIP(s); + matches++; + d = uv_to_utf8(d, uv); + } + else if (uv == none) { + int i; + for (i = UTF8SKIP(s); i; i--) + *d++ = *s++; + } + else if (uv == extra) { + s += UTF8SKIP(s); + matches++; + d = uv_to_utf8(d, final); + } + else + s += UTF8SKIP(s); + } + *d = '\0'; + SvCUR_set(sv, d - (U8*)SvPVX(sv)); + SvSETMAGIC(sv); + } + else if (PL_op->op_private == OPpTRANS_FROM_UTF) { /* no other flags */ + svp = hv_fetch(hv, "FINAL", 5, FALSE); + if (svp) + final = SvUV(*svp); + + d = s; + while (s < send) { + if ((uv = swash_fetch(rv, s)) < none) { + s += UTF8SKIP(s); + matches++; + *d++ = (U8)uv; + } + else if (uv == none) { + I32 ulen; + uv = utf8_to_uv(s, &ulen); + s += ulen; + *d++ = (U8)uv; + } + else if (uv == extra) { + s += UTF8SKIP(s); + matches++; + *d++ = (U8)final; + } + else + s += UTF8SKIP(s); + } + *d = '\0'; + SvCUR_set(sv, d - (U8*)SvPVX(sv)); + SvSETMAGIC(sv); + } + else if (PL_op->op_private == OPpTRANS_TO_UTF) { /* no other flags */ + svp = hv_fetch(hv, "FINAL", 5, FALSE); + if (svp) + final = SvUV(*svp); + + d = s; + while (s < send) { + U8 tmpbuf[10]; + uv_to_utf8(tmpbuf, *s); /* XXX suboptimal */ + if ((uv = swash_fetch(rv, tmpbuf)) < none) { + s += UTF8SKIP(s); + matches++; + d = uv_to_utf8(d, uv); + } + else if (uv == none) { + I32 ulen; + uv = utf8_to_uv(s, &ulen); + s += ulen; + d = uv_to_utf8(d, uv); + } + else if (uv == extra) { + s += UTF8SKIP(s); + matches++; + d = uv_to_utf8(d, final); + } + else + s += UTF8SKIP(s); + } + *d = '\0'; + SvCUR_set(sv, d - (U8*)SvPVX(sv)); + SvSETMAGIC(sv); + } + else if (PL_op->op_private & OPpTRANS_COUNTONLY) { + if (from_utf) { + while (s < send) { + if (swash_fetch(rv, s) < none) + matches++; + s += UTF8SKIP(s); + } } - s++; + else { + while (s < send) { + char tmpbuf[10]; + uv_to_utf8(tmpbuf, *s); /* XXX suboptimal */ + if (swash_fetch(rv, tmpbuf) < none) + matches++; + s += UTF8SKIP(s); + } + } + } + else { + I32 bits = 16; + U8 *dst; + + svp = hv_fetch(hv, "BITS", 4, FALSE); + if (svp) + bits = (I32)SvIV(*svp); + + svp = hv_fetch(hv, "FINAL", 5, FALSE); + if (svp) + final = SvUV(*svp); + + Newz(801, d, len * (bits >> 3) + 1, char); + dst = d; + + puv = 0xfeedface; + if (squash) { + while (s < send) { + if (from_utf) + uv = swash_fetch(rv, s); + else { + char tmpbuf[10]; + uv_to_utf8(tmpbuf, *s); /* XXX suboptimal */ + uv = swash_fetch(rv, tmpbuf); + } + if (uv < none) { + matches++; + if (uv != puv) { + if (to_utf) + d = uv_to_utf8(d, uv); + else + *d++ = (U8)uv; + } + puv = uv; + s += UTF8SKIP(s); + continue; + } + else if (uv == none) { /* "none" is unmapped character */ + int i; + if (to_utf) { + for (i = UTF8SKIP(s); i; --i) + *d++ = *s++; + } + else { + I32 ulen; + *d++ = (U8)utf8_to_uv(s, &ulen); + s += ulen; + } + puv = 0xfeedface; + continue; + } + else if (uv == extra && !del) { + matches++; + if (to_utf) + d = uv_to_utf8(d, final); + else + *d++ = (U8)final; + s += UTF8SKIP(s); + puv = 0xfeedface; + continue; + } + matches++; /* "none+1" is delete character */ + s += UTF8SKIP(s); + } + } + else { + while (s < send) { + if (from_utf) + uv = swash_fetch(rv, s); + else { + char tmpbuf[10]; + uv_to_utf8(tmpbuf, *s); /* XXX suboptimal */ + uv = swash_fetch(rv, tmpbuf); + } + if (uv < none) { + if (to_utf) + d = uv_to_utf8(d, uv); + else + *d++ = (U8)uv; + matches++; + s += UTF8SKIP(s); + continue; + } + else if (uv == none) { /* "none" is unmapped character */ + int i; + if (to_utf) { + for (i = UTF8SKIP(s); i; --i) + *d++ = *s++; + } + else { + I32 ulen; + *d++ = (U8)utf8_to_uv(s, &ulen); + s += ulen; + } + continue; + } + else if (uv == extra && !del) { + matches++; + if (to_utf) + d = uv_to_utf8(d, final); + else + *d++ = (U8)final; + s += UTF8SKIP(s); + continue; + } + matches++; /* "none+1" is delete character */ + s += UTF8SKIP(s); + } + } + sv_usepvn_mg(sv, dst, d - dst); } + return matches; } else { - d = s; - while (s < send) { - if ((ch = tbl[*s]) >= 0) { - *d = ch; - if (matches++ && squash) { - if (d[-1] == *d) - matches--; + register short *tbl; + register I32 ch; + register U8 *p; + + tbl = (short*)cPVOP->op_pv; + s = (U8*)SvPV(sv, len); + if (!len) + return 0; + if (!SvPOKp(sv)) + s = (U8*)SvPV_force(sv, len); + (void)SvPOK_only(sv); + send = s + len; + if (!tbl || !s) + croak("panic: do_trans"); + DEBUG_t( deb("2.TBL\n")); + if (!PL_op->op_private) { + while (s < send) { + if ((ch = tbl[*s]) >= 0) { + matches++; + *s = ch; + } + s++; + } + SvSETMAGIC(sv); + } + else if (PL_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; + matches++; + if (squash) { + if (p == d - 1 && *p == *d) + matches--; + else + p = d++; + } else d++; } - else - d++; + else if (ch == -1) /* -1 is unmapped character */ + *d++ = *s; /* -2 is delete character */ + s++; } - else if (ch == -1) /* -1 is unmapped character */ - *d++ = *s; /* -2 is delete character */ - s++; + matches += send - d; /* account for disappeared chars */ + *d = '\0'; + SvCUR_set(sv, d - (U8*)SvPVX(sv)); + SvSETMAGIC(sv); } - matches += send - d; /* account for disappeared chars */ - *d = '\0'; - SvCUR_set(sv, d - (U8*)SvPVX(sv)); + return matches; } - SvSETMAGIC(sv); - return matches; } void -do_join(sv,del,mark,sp) -register SV *sv; -SV *del; -register SV **mark; -register SV **sp; +do_join(register SV *sv, SV *del, register SV **mark, register SV **sp) { SV **oldmark = mark; register I32 items = sp - mark; @@ -109,7 +354,7 @@ register SV **sp; sv_upgrade(sv, SVt_PV); if (SvLEN(sv) < len + items) { /* current length is way too short */ while (items-- > 0) { - if (*mark) { + if (*mark && !SvGMAGICAL(*mark) && SvOK(*mark)) { SvPV(*mark, tmplen); len += tmplen; } @@ -150,202 +395,20 @@ register SV **sp; } void -do_sprintf(sv,len,sarg) -register SV *sv; -register I32 len; -register SV **sarg; +do_sprintf(SV *sv, I32 len, SV **sarg) { - register char *s; - register char *t; - register char *f; - bool dolong; -#ifdef HAS_QUAD - bool doquad; -#endif /* HAS_QUAD */ - char ch; - register char *send; - register SV *arg; - char *xs; - I32 xlen; - I32 pre; - I32 post; - double value; - STRLEN arglen; - - sv_setpv(sv,""); - len--; /* don't count pattern string */ - t = s = SvPV(*sarg, arglen); /* XXX Don't know t is writeable */ - send = s + arglen; - sarg++; - for ( ; ; len--) { - - /*SUPPRESS 560*/ - if (len <= 0 || !(arg = *sarg++)) - arg = &sv_no; - - /*SUPPRESS 530*/ - for ( ; t < send && *t != '%'; t++) ; - if (t >= send) - break; /* end of run_format string, ignore extra args */ - f = t; - *buf = '\0'; - xs = buf; -#ifdef HAS_QUAD - doquad = -#endif /* HAS_QUAD */ - dolong = FALSE; - pre = post = 0; - for (t++; t < send; t++) { - switch (*t) { - default: - ch = *(++t); - *t = '\0'; - (void)sprintf(xs,f); - len++, sarg--; - xlen = strlen(xs); - break; - case 'n': case '*': - croak("Use of %c in printf format not supported", *t); - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case '.': case '#': case '-': case '+': case ' ': - continue; - case 'l': -#ifdef HAS_QUAD - if (dolong) { - dolong = FALSE; - doquad = TRUE; - } else -#endif - dolong = TRUE; - continue; - case 'c': - ch = *(++t); - *t = '\0'; - xlen = SvIV(arg); - if (strEQ(f,"%c")) { /* some printfs fail on null chars */ - *xs = xlen; - xs[1] = '\0'; - xlen = 1; - } - else { - (void)sprintf(xs,f,xlen); - xlen = strlen(xs); - } - break; - case 'D': - dolong = TRUE; - /* FALL THROUGH */ - case 'd': - ch = *(++t); - *t = '\0'; -#ifdef HAS_QUAD - if (doquad) - (void)sprintf(buf,s,(Quad_t)SvNV(arg)); - else -#endif - if (dolong) - (void)sprintf(xs,f,(long)SvNV(arg)); - else - (void)sprintf(xs,f,SvIV(arg)); - xlen = strlen(xs); - break; - case 'X': case 'O': - dolong = TRUE; - /* FALL THROUGH */ - case 'x': case 'o': case 'u': - ch = *(++t); - *t = '\0'; - value = SvNV(arg); -#ifdef HAS_QUAD - if (doquad) - (void)sprintf(buf,s,(unsigned Quad_t)value); - else -#endif - if (dolong) - (void)sprintf(xs,f,U_L(value)); - else - (void)sprintf(xs,f,U_I(value)); - xlen = strlen(xs); - break; - case 'E': case 'e': case 'f': case 'G': case 'g': - ch = *(++t); - *t = '\0'; - (void)sprintf(xs,f,SvNV(arg)); - xlen = strlen(xs); - break; - case 's': - ch = *(++t); - *t = '\0'; - xs = SvPV(arg, arglen); - xlen = (I32)arglen; - if (strEQ(f,"%s")) { /* some printfs fail on >128 chars */ - break; /* so handle simple cases */ - } - else if (f[1] == '-') { - char *mp = strchr(f, '.'); - I32 min = atoi(f+2); - - if (mp) { - I32 max = atoi(mp+1); - - if (xlen > max) - xlen = max; - } - if (xlen < min) - post = min - xlen; - break; - } - else if (isDIGIT(f[1])) { - char *mp = strchr(f, '.'); - I32 min = atoi(f+1); - - if (mp) { - I32 max = atoi(mp+1); + STRLEN patlen; + char *pat = SvPV(*sarg, patlen); + bool do_taint = FALSE; - if (xlen > max) - xlen = max; - } - if (xlen < min) - pre = min - xlen; - break; - } - strcpy(tokenbuf+64,f); /* sprintf($s,...$s...) */ - *t = ch; - (void)sprintf(buf,tokenbuf+64,xs); - xs = buf; - xlen = strlen(xs); - break; - } - /* end of switch, copy results */ - *t = ch; - if (xs == buf && xlen >= sizeof(buf)) { /* Ooops! */ - fputs("panic: sprintf overflow - memory corrupted!\n",stderr); - my_exit(1); - } - SvGROW(sv, SvCUR(sv) + (f - s) + xlen + 1 + pre + post); - sv_catpvn(sv, s, f - s); - if (pre) { - repeatcpy(SvPVX(sv) + SvCUR(sv), " ", 1, pre); - SvCUR(sv) += pre; - } - sv_catpvn(sv, xs, xlen); - if (post) { - repeatcpy(SvPVX(sv) + SvCUR(sv), " ", 1, post); - SvCUR(sv) += post; - } - s = t; - break; /* break from for loop */ - } - } - sv_catpvn(sv, s, t - s); + sv_vsetpvfn(sv, pat, patlen, Null(va_list*), sarg + 1, len - 1, &do_taint); SvSETMAGIC(sv); + if (do_taint) + SvTAINTED_on(sv); } void -do_vecset(sv) -SV *sv; +do_vecset(SV *sv) { SV *targ = LvTARG(sv); register I32 offset; @@ -396,9 +459,7 @@ SV *sv; } void -do_chop(astr,sv) -register SV *astr; -register SV *sv; +do_chop(register SV *astr, register SV *sv) { STRLEN len; char *s; @@ -410,7 +471,7 @@ register SV *sv; max = AvFILL(av); for (i = 0; i <= max; i++) { sv = (SV*)av_fetch(av, i, FALSE); - if (sv && ((sv = *(SV**)sv), sv != &sv_undef)) + if (sv && ((sv = *(SV**)sv), sv != &PL_sv_undef)) do_chop(astr, sv); } return; @@ -427,6 +488,24 @@ register SV *sv; s = SvPV(sv, len); if (len && !SvPOK(sv)) s = SvPV_force(sv, len); + if (IN_UTF8) { + if (s && len) { + char *send = s + len; + char *start = s; + s = send - 1; + while ((*s & 0xc0) == 0x80) + --s; + if (UTF8SKIP(s) != send - s) + warn("Malformed UTF-8 character"); + sv_setpvn(astr, s, send - s); + *s = '\0'; + SvCUR_set(sv, s - start); + SvNIOK_off(sv); + } + else + sv_setpvn(astr, "", 0); + } + else if (s && len) { s += --len; sv_setpvn(astr, s, 1); @@ -440,14 +519,14 @@ register SV *sv; } I32 -do_chomp(sv) -register SV *sv; +do_chomp(register SV *sv) { + dTHR; register I32 count; STRLEN len; char *s; - if (RsSNARF(rs)) + if (RsSNARF(PL_rs)) return 0; count = 0; if (SvTYPE(sv) == SVt_PVAV) { @@ -457,7 +536,7 @@ register SV *sv; max = AvFILL(av); for (i = 0; i <= max; i++) { sv = (SV*)av_fetch(av, i, FALSE); - if (sv && ((sv = *(SV**)sv), sv != &sv_undef)) + if (sv && ((sv = *(SV**)sv), sv != &PL_sv_undef)) count += do_chomp(sv); } return count; @@ -476,7 +555,7 @@ register SV *sv; s = SvPV_force(sv, len); if (s && len) { s += --len; - if (RsPARA(rs)) { + if (RsPARA(PL_rs)) { if (*s != '\n') goto nope; ++count; @@ -488,18 +567,18 @@ register SV *sv; } else { STRLEN rslen; - char *rsptr = SvPV(rs, rslen); + char *rsptr = SvPV(PL_rs, rslen); if (rslen == 1) { if (*s != *rsptr) goto nope; ++count; } else { - if (len < rslen) + if (len < rslen - 1) goto nope; len -= rslen - 1; s -= rslen - 1; - if (bcmp(s, rsptr, rslen)) + if (memNE(s, rsptr, rslen)) goto nope; count += rslen; } @@ -514,12 +593,9 @@ register SV *sv; } void -do_vop(optype,sv,left,right) -I32 optype; -SV *sv; -SV *left; -SV *right; +do_vop(I32 optype, SV *sv, SV *left, SV *right) { + dTHR; /* just for taint */ #ifdef LIBERAL register long *dl; register long *ll; @@ -528,17 +604,32 @@ SV *right; register char *dc; STRLEN leftlen; STRLEN rightlen; - register char *lc = SvPV(left, leftlen); - register char *rc = SvPV(right, rightlen); + register char *lc; + register char *rc; register I32 len; I32 lensave; + char *lsave; + char *rsave; - dc = SvPV_force(sv,na); + if (sv != left || (optype != OP_BIT_AND && !SvOK(sv) && !SvGMAGICAL(sv))) + sv_setpvn(sv, "", 0); /* avoid undef warning on |= and ^= */ + lsave = lc = SvPV(left, leftlen); + rsave = rc = SvPV(right, rightlen); len = leftlen < rightlen ? leftlen : rightlen; lensave = len; - if (SvCUR(sv) < len) { - dc = SvGROW(sv,len + 1); - (void)memzero(dc + SvCUR(sv), len - SvCUR(sv) + 1); + if (SvOK(sv) || SvTYPE(sv) > SVt_PVMG) { + dc = SvPV_force(sv, PL_na); + if (SvCUR(sv) < len) { + dc = SvGROW(sv, len + 1); + (void)memzero(dc + SvCUR(sv), len - SvCUR(sv) + 1); + } + } + else { + I32 needlen = ((optype == OP_BIT_AND) + ? len : (leftlen > rightlen ? leftlen : rightlen)); + Newz(801, dc, needlen + 1, char); + (void)sv_usepvn(sv, dc, needlen); + dc = SvPVX(sv); /* sv_usepvn() calls Renew() */ } SvCUR_set(sv, len); (void)SvPOK_only(sv); @@ -589,9 +680,6 @@ SV *right; } #endif { - char *lsave = lc; - char *rsave = rc; - switch (optype) { case OP_BIT_AND: while (len--) @@ -615,68 +703,89 @@ SV *right; break; } } + SvTAINT(sv); } OP * -do_kv(ARGS) -dARGS +do_kv(ARGSproto) { - dSP; + djSP; HV *hv = (HV*)POPs; - I32 i; + HV *keys; register HE *entry; - char *tmps; SV *tmpstr; - I32 dokeys = (op->op_type == OP_KEYS); - I32 dovalues = (op->op_type == OP_VALUES); - - if (op->op_type == OP_RV2HV || op->op_type == OP_PADHV) + I32 gimme = GIMME_V; + I32 dokeys = (PL_op->op_type == OP_KEYS); + I32 dovalues = (PL_op->op_type == OP_VALUES); + I32 realhv = (SvTYPE(hv) == SVt_PVHV); + + if (PL_op->op_type == OP_RV2HV || PL_op->op_type == OP_PADHV) dokeys = dovalues = TRUE; - if (!hv) + if (!hv) { + if (PL_op->op_flags & OPf_MOD) { /* lvalue */ + dTARGET; /* make sure to clear its target here */ + if (SvTYPE(TARG) == SVt_PVLV) + LvTARG(TARG) = Nullsv; + PUSHs(TARG); + } RETURN; + } - (void)hv_iterinit(hv); /* always reset iterator regardless */ + keys = realhv ? hv : avhv_keys((AV*)hv); + (void)hv_iterinit(keys); /* always reset iterator regardless */ - if (GIMME != G_ARRAY) { + if (gimme == G_VOID) + RETURN; + + if (gimme == G_SCALAR) { + IV i; dTARGET; - if (!SvRMAGICAL(hv) || !mg_find((SV*)hv,'P')) - i = HvKEYS(hv); + if (PL_op->op_flags & OPf_MOD) { /* lvalue */ + if (SvTYPE(TARG) < SVt_PVLV) { + sv_upgrade(TARG, SVt_PVLV); + sv_magic(TARG, Nullsv, 'k', Nullch, 0); + } + LvTYPE(TARG) = 'k'; + if (LvTARG(TARG) != (SV*)keys) { + if (LvTARG(TARG)) + SvREFCNT_dec(LvTARG(TARG)); + LvTARG(TARG) = SvREFCNT_inc(keys); + } + PUSHs(TARG); + RETURN; + } + + if (!SvRMAGICAL(keys) || !mg_find((SV*)keys,'P')) + i = HvKEYS(keys); else { i = 0; /*SUPPRESS 560*/ - while (entry = hv_iternext(hv)) { - i++; - } + while (hv_iternext(keys)) i++; } PUSHi( i ); RETURN; } - /* Guess how much room we need. hv_max may be a few too many. Oh well. */ - EXTEND(sp, HvMAX(hv) * (dokeys + dovalues)); + EXTEND(SP, HvKEYS(keys) * (dokeys + dovalues)); PUTBACK; /* hv_iternext and hv_iterval might clobber stack_sp */ - while (entry = hv_iternext(hv)) { + while (entry = hv_iternext(keys)) { SPAGAIN; - if (dokeys) { - tmps = hv_iterkey(entry,&i); /* won't clobber stack_sp */ - if (!i) - tmps = ""; - XPUSHs(sv_2mortal(newSVpv(tmps,i))); - } + if (dokeys) + XPUSHs(hv_iterkeysv(entry)); /* won't clobber stack_sp */ if (dovalues) { - tmpstr = NEWSV(45,0); + tmpstr = sv_newmortal(); PUTBACK; - sv_setsv(tmpstr,hv_iterval(hv,entry)); + sv_setsv(tmpstr,realhv ? + hv_iterval(hv,entry) : avhv_iterval((AV*)hv,entry)); + DEBUG_H(sv_setpvf(tmpstr, "%lu%%%d=%lu", + (unsigned long)HeHASH(entry), + HvMAX(keys)+1, + (unsigned long)(HeHASH(entry) & HvMAX(keys)))); SPAGAIN; - DEBUG_H( { - sprintf(buf,"%d%%%d=%d\n",entry->hent_hash, - HvMAX(hv)+1,entry->hent_hash & HvMAX(hv)); - sv_setpv(tmpstr,buf); - } ) - XPUSHs(sv_2mortal(tmpstr)); + XPUSHs(tmpstr); } PUTBACK; }