X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=dump.c;h=98405c6fad434a706b2aff95653221f479d015f3;hb=3df15adcc3686bbc809ac9706048f258fd787941;hp=ad641900ae0156fc8a2a6d42fdea054599b31d94;hpb=b123ab9da00617145bdd8b4b325a5f78afda05c1;p=p5sagit%2Fp5-mst-13.2.git diff --git a/dump.c b/dump.c index ad64190..98405c6 100644 --- a/dump.c +++ b/dump.c @@ -119,40 +119,121 @@ Perl_dump_eval(pTHX) op_dump(PL_eval_root); } -char * -Perl_pv_display(pTHX_ SV *dsv, const char *pv, STRLEN cur, STRLEN len, STRLEN pvlim) -{ - const bool nul_terminated = len > cur && pv[cur] == '\0'; - bool truncated = 0; - sv_setpvn(dsv, "\"", 1); - for (; cur--; pv++) { - if (pvlim && SvCUR(dsv) >= pvlim) { - truncated = 1; - break; - } - switch (*pv) { - case '\t': sv_catpvs(dsv, "\\t"); break; - case '\n': sv_catpvs(dsv, "\\n"); break; - case '\r': sv_catpvs(dsv, "\\r"); break; - case '\f': sv_catpvs(dsv, "\\f"); break; - case '"': sv_catpvs(dsv, "\\\""); break; - case '\\': sv_catpvs(dsv, "\\\\"); break; - default: - if (isPRINT(*pv)) - sv_catpvn(dsv, pv, 1); - else if (cur && isDIGIT(*(pv+1))) - Perl_sv_catpvf(aTHX_ dsv, "\\%03o", (U8)*pv); - else - Perl_sv_catpvf(aTHX_ dsv, "\\%o", (U8)*pv); - } +/* +=for apidoc Apd|char*|pv_escape|NN SV *dsv|NN const char *pv|const STRLEN count|const STRLEN max|const U32 flags + +Escapes at most the first "count" chars of pv and puts the results into +buf such that the size of the escaped string will not exceed "max" chars +and will not contain any incomplete escape sequences. + +If flags contains PERL_PV_ESCAPE_QUOTE then the string will have quotes +placed around it; moreover, if the number of chars converted was less than +"count" then a trailing elipses (...) will be added after the closing +quote. + +If PERL_PV_ESCAPE_QUOTE is not set, but PERL_PV_ESCAPE_PADR is, then the +returned string will be right padded with spaces such that it is max chars +long. + +Normally the SV will be cleared before the escaped string is prepared, +but when PERL_PV_ESCAPE_CAT is set this will not occur. + +Returns a pointer to the string contained by SV. + +=cut +*/ + +char * +Perl_pv_escape( pTHX_ SV *dsv, const char *pv, const STRLEN count, const STRLEN max, const U32 flags ) { + char dq = (flags & PERL_PV_ESCAPE_QUOTE) ? '"' : '\\'; + char octbuf[8] = "\\0123456"; + STRLEN wrote = 0; + STRLEN chsize = 0; + const char *end = pv + count; + + if (flags & PERL_PV_ESCAPE_CAT) { + if ( dq == '"' ) + sv_catpvn(dsv, "\"", 1); + } else { + if ( dq == '"' ) + sv_setpvn(dsv, "\"", 1); + else + sv_setpvn(dsv, "", 0); + } + for ( ; (pv < end && (!max || (wrote < max))) ; pv++ ) { + if ( (*pv == dq) || (*pv == '\\') || isCNTRL(*pv) ) { + chsize = 2; + switch (*pv) { + case '\\' : octbuf[1] = '\\'; break; + case '\v' : octbuf[1] = 'v'; break; + case '\t' : octbuf[1] = 't'; break; + case '\r' : octbuf[1] = 'r'; break; + case '\n' : octbuf[1] = 'n'; break; + case '\f' : octbuf[1] = 'f'; break; + case '"' : if ( dq == *pv ) { + octbuf[1] = '"'; + break; + } + default: + /* note the (U8*) casts here are important. + * if they are omitted we can produce the octal + * for a negative number which could produce a + * buffer overrun in octbuf, with it on we are + * guaranteed that the longest the string could be + * is 5, (we reserve 8 just because its the first + * power of 2 larger than 5.)*/ + if ( (pv < end) && isDIGIT(*(pv+1)) ) + chsize = sprintf( octbuf, "\\%03o", (U8)*pv); + else + chsize = sprintf( octbuf, "\\%o", (U8)*pv); + } + if ( max && (wrote + chsize > max) ) { + break; + } else { + sv_catpvn(dsv, octbuf, chsize); + wrote += chsize; + } + } else { + sv_catpvn(dsv, pv, 1); + wrote++; + } } - sv_catpvs(dsv, "\""); - if (truncated) - sv_catpvs(dsv, "..."); - if (nul_terminated) - sv_catpvs(dsv, "\\0"); + if ( dq == '"' ) { + sv_catpvn( dsv, "\"", 1 ); + if ( pv < end ) + sv_catpvn( dsv, "...", 3 ); + } else if ( max && (flags & PERL_PV_ESCAPE_PADR) ) { + for ( ; wrote < max ; wrote++ ) + sv_catpvn( dsv, " ", 1 ); + } + return SvPVX(dsv); +} + +/* +=for apidoc pv_display + + char *pv_display(SV *dsv, const char *pv, STRLEN cur, STRLEN len, + STRLEN pvlim, U32 flags) + +Similar to + pv_escape(dsv,pv,cur,pvlim,PERL_PV_ESCAPE_QUOTE); + +except that an additional "\0" will be appended to the string when +len > cur and pv[cur] is "\0". + +Note that the final string may be up to 7 chars longer than pvlim. + +=cut +*/ + +char * +Perl_pv_display(pTHX_ SV *dsv, const char *pv, STRLEN cur, STRLEN len, STRLEN pvlim) +{ + pv_escape( dsv, pv, cur, pvlim, PERL_PV_ESCAPE_QUOTE); + if (len > cur && pv[cur] == '\0') + sv_catpvn( dsv, "\\0", 2 ); return SvPVX(dsv); } @@ -305,7 +386,7 @@ Perl_sv_peek(pTHX_ SV *sv) if (!SvPVX_const(sv)) sv_catpv(t, "(null)"); else { - SV *tmp = newSVpvs(""); + SV * const tmp = newSVpvs(""); sv_catpv(t, "("); if (SvOOK(sv)) Perl_sv_catpvf(aTHX_ t, "[%s]", pv_display(tmp, SvPVX_const(sv)-SvIVX(sv), SvIVX(sv), 0, 127)); @@ -365,33 +446,7 @@ Perl_do_pmop_dump(pTHX_ I32 level, PerlIO *file, const PMOP *pm) op_dump(pm->op_pmreplroot); } if (pm->op_pmflags || (PM_GETRE(pm) && PM_GETRE(pm)->check_substr)) { - SV *tmpsv = newSVpvs(""); - if (pm->op_pmdynflags & PMdf_USED) - sv_catpv(tmpsv, ",USED"); - if (pm->op_pmdynflags & PMdf_TAINTED) - sv_catpv(tmpsv, ",TAINTED"); - if (pm->op_pmflags & PMf_ONCE) - sv_catpv(tmpsv, ",ONCE"); - if (PM_GETRE(pm) && PM_GETRE(pm)->check_substr - && !(PM_GETRE(pm)->reganch & ROPT_NOSCAN)) - sv_catpv(tmpsv, ",SCANFIRST"); - if (PM_GETRE(pm) && PM_GETRE(pm)->check_substr - && PM_GETRE(pm)->reganch & ROPT_CHECK_ALL) - sv_catpv(tmpsv, ",ALL"); - if (pm->op_pmflags & PMf_SKIPWHITE) - sv_catpv(tmpsv, ",SKIPWHITE"); - if (pm->op_pmflags & PMf_CONST) - sv_catpv(tmpsv, ",CONST"); - if (pm->op_pmflags & PMf_KEEP) - sv_catpv(tmpsv, ",KEEP"); - if (pm->op_pmflags & PMf_GLOBAL) - sv_catpv(tmpsv, ",GLOBAL"); - if (pm->op_pmflags & PMf_CONTINUE) - sv_catpv(tmpsv, ",CONTINUE"); - if (pm->op_pmflags & PMf_RETAINT) - sv_catpv(tmpsv, ",RETAINT"); - if (pm->op_pmflags & PMf_EVAL) - sv_catpv(tmpsv, ",EVAL"); + SV * const tmpsv = pm_description(pm); Perl_dump_indent(aTHX_ level, file, "PMFLAGS = (%s)\n", SvCUR(tmpsv) ? SvPVX_const(tmpsv) + 1 : ""); SvREFCNT_dec(tmpsv); } @@ -399,6 +454,43 @@ Perl_do_pmop_dump(pTHX_ I32 level, PerlIO *file, const PMOP *pm) Perl_dump_indent(aTHX_ level-1, file, "}\n"); } +static SV * +S_pm_description(pTHX_ const PMOP *pm) +{ + SV * const desc = newSVpvs(""); + const REGEXP * regex = PM_GETRE(pm); + const U32 pmflags = pm->op_pmflags; + + if (pm->op_pmdynflags & PMdf_USED) + sv_catpv(desc, ",USED"); + if (pm->op_pmdynflags & PMdf_TAINTED) + sv_catpv(desc, ",TAINTED"); + + if (pmflags & PMf_ONCE) + sv_catpv(desc, ",ONCE"); + if (regex && regex->check_substr) { + if (!(regex->reganch & ROPT_NOSCAN)) + sv_catpv(desc, ",SCANFIRST"); + if (regex->reganch & ROPT_CHECK_ALL) + sv_catpv(desc, ",ALL"); + } + if (pmflags & PMf_SKIPWHITE) + sv_catpv(desc, ",SKIPWHITE"); + if (pmflags & PMf_CONST) + sv_catpv(desc, ",CONST"); + if (pmflags & PMf_KEEP) + sv_catpv(desc, ",KEEP"); + if (pmflags & PMf_GLOBAL) + sv_catpv(desc, ",GLOBAL"); + if (pmflags & PMf_CONTINUE) + sv_catpv(desc, ",CONTINUE"); + if (pmflags & PMf_RETAINT) + sv_catpv(desc, ",RETAINT"); + if (pmflags & PMf_EVAL) + sv_catpv(desc, ",EVAL"); + return desc; +} + void Perl_pmop_dump(pTHX_ PMOP *pm) { @@ -411,11 +503,7 @@ STATIC void S_sequence(pTHX_ register const OP *o) { dVAR; - SV *op; - const char *key; - STRLEN len; const OP *oldop = NULL; - OP *l; if (!o) return; @@ -429,8 +517,10 @@ S_sequence(pTHX_ register const OP *o) Sequence = newHV(); for (; o; o = o->op_next) { - op = newSVuv(PTR2UV(o)); - key = SvPV_const(op, len); + STRLEN len; + SV * const op = newSVuv(PTR2UV(o)); + const char * const key = SvPV_const(op, len); + if (hv_exists(Sequence, key, len)) break; @@ -469,32 +559,22 @@ S_sequence(pTHX_ register const OP *o) case OP_COND_EXPR: case OP_RANGE: hv_store(Sequence, key, len, newSVuv(++PL_op_seq), 0); - for (l = cLOGOPo->op_other; l && l->op_type == OP_NULL; l = l->op_next) - ; - sequence(l); + sequence_tail(cLOGOPo->op_other); break; case OP_ENTERLOOP: case OP_ENTERITER: hv_store(Sequence, key, len, newSVuv(++PL_op_seq), 0); - for (l = cLOOPo->op_redoop; l && l->op_type == OP_NULL; l = l->op_next) - ; - sequence(l); - for (l = cLOOPo->op_nextop; l && l->op_type == OP_NULL; l = l->op_next) - ; - sequence(l); - for (l = cLOOPo->op_lastop; l && l->op_type == OP_NULL; l = l->op_next) - ; - sequence(l); + sequence_tail(cLOOPo->op_redoop); + sequence_tail(cLOOPo->op_nextop); + sequence_tail(cLOOPo->op_lastop); break; case OP_QR: case OP_MATCH: case OP_SUBST: hv_store(Sequence, key, len, newSVuv(++PL_op_seq), 0); - for (l = cPMOPo->op_pmreplstart; l && l->op_type == OP_NULL; l = l->op_next) - ; - sequence(l); + sequence_tail(cPMOPo->op_pmreplstart); break; case OP_HELEM: @@ -508,6 +588,14 @@ S_sequence(pTHX_ register const OP *o) } } +static void +S_sequence_tail(pTHX_ const OP *o) +{ + while (o && (o->op_type == OP_NULL)) + o = o->op_next; + sequence(o); +} + STATIC UV S_sequence_num(pTHX_ const OP *o) { @@ -528,6 +616,8 @@ Perl_do_op_dump(pTHX_ I32 level, PerlIO *file, const OP *o) { dVAR; UV seq; + const OPCODE optype = o->op_type; + sequence(o); Perl_dump_indent(aTHX_ level, file, "{\n"); level++; @@ -545,11 +635,9 @@ Perl_do_op_dump(pTHX_ I32 level, PerlIO *file, const OP *o) else PerlIO_printf(file, "DONE\n"); if (o->op_targ) { - if (o->op_type == OP_NULL) - { + if (optype == OP_NULL) { Perl_dump_indent(aTHX_ level, file, " (was %s)\n", PL_op_name[o->op_targ]); - if (o->op_targ == OP_NEXTSTATE) - { + if (o->op_targ == OP_NEXTSTATE) { if (CopLINE(cCOPo)) Perl_dump_indent(aTHX_ level, file, "LINE = %"UVf"\n", (UV)CopLINE(cCOPo)); @@ -568,7 +656,7 @@ Perl_do_op_dump(pTHX_ I32 level, PerlIO *file, const OP *o) Perl_dump_indent(aTHX_ level, file, "ADDR = 0x%"UVxf" => 0x%"UVxf"\n", (UV)o, (UV)o->op_next); #endif if (o->op_flags) { - SV *tmpsv = newSVpvs(""); + SV * const tmpsv = newSVpvs(""); switch (o->op_flags & OPf_WANT) { case OPf_WANT_VOID: sv_catpv(tmpsv, ",VOID"); @@ -599,27 +687,27 @@ Perl_do_op_dump(pTHX_ I32 level, PerlIO *file, const OP *o) SvREFCNT_dec(tmpsv); } if (o->op_private) { - SV *tmpsv = newSVpvs(""); - if (PL_opargs[o->op_type] & OA_TARGLEX) { + SV * const tmpsv = newSVpvs(""); + if (PL_opargs[optype] & OA_TARGLEX) { if (o->op_private & OPpTARGET_MY) sv_catpv(tmpsv, ",TARGET_MY"); } - else if (o->op_type == OP_LEAVESUB || - o->op_type == OP_LEAVE || - o->op_type == OP_LEAVESUBLV || - o->op_type == OP_LEAVEWRITE) { + else if (optype == OP_LEAVESUB || + optype == OP_LEAVE || + optype == OP_LEAVESUBLV || + optype == OP_LEAVEWRITE) { if (o->op_private & OPpREFCOUNTED) sv_catpv(tmpsv, ",REFCOUNTED"); } - else if (o->op_type == OP_AASSIGN) { + else if (optype == OP_AASSIGN) { if (o->op_private & OPpASSIGN_COMMON) sv_catpv(tmpsv, ",COMMON"); } - else if (o->op_type == OP_SASSIGN) { + else if (optype == OP_SASSIGN) { if (o->op_private & OPpASSIGN_BACKWARDS) sv_catpv(tmpsv, ",BACKWARDS"); } - else if (o->op_type == OP_TRANS) { + else if (optype == OP_TRANS) { if (o->op_private & OPpTRANS_SQUASH) sv_catpv(tmpsv, ",SQUASH"); if (o->op_private & OPpTRANS_DELETE) @@ -631,20 +719,20 @@ Perl_do_op_dump(pTHX_ I32 level, PerlIO *file, const OP *o) if (o->op_private & OPpTRANS_GROWS) sv_catpv(tmpsv, ",GROWS"); } - else if (o->op_type == OP_REPEAT) { + else if (optype == OP_REPEAT) { if (o->op_private & OPpREPEAT_DOLIST) sv_catpv(tmpsv, ",DOLIST"); } - else if (o->op_type == OP_ENTERSUB || - o->op_type == OP_RV2SV || - o->op_type == OP_GVSV || - o->op_type == OP_RV2AV || - o->op_type == OP_RV2HV || - o->op_type == OP_RV2GV || - o->op_type == OP_AELEM || - o->op_type == OP_HELEM ) + else if (optype == OP_ENTERSUB || + optype == OP_RV2SV || + optype == OP_GVSV || + optype == OP_RV2AV || + optype == OP_RV2HV || + optype == OP_RV2GV || + optype == OP_AELEM || + optype == OP_HELEM ) { - if (o->op_type == OP_ENTERSUB) { + if (optype == OP_ENTERSUB) { if (o->op_private & OPpENTERSUB_AMPER) sv_catpv(tmpsv, ",AMPER"); if (o->op_private & OPpENTERSUB_DB) @@ -660,20 +748,20 @@ Perl_do_op_dump(pTHX_ I32 level, PerlIO *file, const OP *o) } else { switch (o->op_private & OPpDEREF) { - case OPpDEREF_SV: - sv_catpv(tmpsv, ",SV"); - break; - case OPpDEREF_AV: - sv_catpv(tmpsv, ",AV"); - break; - case OPpDEREF_HV: - sv_catpv(tmpsv, ",HV"); - break; - } + case OPpDEREF_SV: + sv_catpv(tmpsv, ",SV"); + break; + case OPpDEREF_AV: + sv_catpv(tmpsv, ",AV"); + break; + case OPpDEREF_HV: + sv_catpv(tmpsv, ",HV"); + break; + } if (o->op_private & OPpMAYBE_LVSUB) sv_catpv(tmpsv, ",MAYBE_LVSUB"); } - if (o->op_type == OP_AELEM || o->op_type == OP_HELEM) { + if (optype == OP_AELEM || optype == OP_HELEM) { if (o->op_private & OPpLVAL_DEFER) sv_catpv(tmpsv, ",LVAL_DEFER"); } @@ -684,7 +772,7 @@ Perl_do_op_dump(pTHX_ I32 level, PerlIO *file, const OP *o) sv_catpv(tmpsv, ",OUR_INTRO"); } } - else if (o->op_type == OP_CONST) { + else if (optype == OP_CONST) { if (o->op_private & OPpCONST_BARE) sv_catpv(tmpsv, ",BARE"); if (o->op_private & OPpCONST_STRICT) @@ -696,35 +784,35 @@ Perl_do_op_dump(pTHX_ I32 level, PerlIO *file, const OP *o) if (o->op_private & OPpCONST_ENTERED) sv_catpv(tmpsv, ",ENTERED"); } - else if (o->op_type == OP_FLIP) { + else if (optype == OP_FLIP) { if (o->op_private & OPpFLIP_LINENUM) sv_catpv(tmpsv, ",LINENUM"); } - else if (o->op_type == OP_FLOP) { + else if (optype == OP_FLOP) { if (o->op_private & OPpFLIP_LINENUM) sv_catpv(tmpsv, ",LINENUM"); } - else if (o->op_type == OP_RV2CV) { + else if (optype == OP_RV2CV) { if (o->op_private & OPpLVAL_INTRO) sv_catpv(tmpsv, ",INTRO"); } - else if (o->op_type == OP_GV) { + else if (optype == OP_GV) { if (o->op_private & OPpEARLY_CV) sv_catpv(tmpsv, ",EARLY_CV"); } - else if (o->op_type == OP_LIST) { + else if (optype == OP_LIST) { if (o->op_private & OPpLIST_GUESSED) sv_catpv(tmpsv, ",GUESSED"); } - else if (o->op_type == OP_DELETE) { + else if (optype == OP_DELETE) { if (o->op_private & OPpSLICE) sv_catpv(tmpsv, ",SLICE"); } - else if (o->op_type == OP_EXISTS) { + else if (optype == OP_EXISTS) { if (o->op_private & OPpEXISTS_SUB) sv_catpv(tmpsv, ",EXISTS_SUB"); } - else if (o->op_type == OP_SORT) { + else if (optype == OP_SORT) { if (o->op_private & OPpSORT_NUMERIC) sv_catpv(tmpsv, ",NUMERIC"); if (o->op_private & OPpSORT_INTEGER) @@ -732,11 +820,11 @@ Perl_do_op_dump(pTHX_ I32 level, PerlIO *file, const OP *o) if (o->op_private & OPpSORT_REVERSE) sv_catpv(tmpsv, ",REVERSE"); } - else if (o->op_type == OP_THREADSV) { + else if (optype == OP_THREADSV) { if (o->op_private & OPpDONE_SVREF) sv_catpv(tmpsv, ",SVREF"); } - else if (o->op_type == OP_OPEN || o->op_type == OP_BACKTICK) { + else if (optype == OP_OPEN || optype == OP_BACKTICK) { if (o->op_private & OPpOPEN_IN_RAW) sv_catpv(tmpsv, ",IN_RAW"); if (o->op_private & OPpOPEN_IN_CRLF) @@ -746,17 +834,17 @@ Perl_do_op_dump(pTHX_ I32 level, PerlIO *file, const OP *o) if (o->op_private & OPpOPEN_OUT_CRLF) sv_catpv(tmpsv, ",OUT_CRLF"); } - else if (o->op_type == OP_EXIT) { + else if (optype == OP_EXIT) { if (o->op_private & OPpEXIT_VMSISH) sv_catpv(tmpsv, ",EXIT_VMSISH"); if (o->op_private & OPpHUSH_VMSISH) sv_catpv(tmpsv, ",HUSH_VMSISH"); } - else if (o->op_type == OP_DIE) { + else if (optype == OP_DIE) { if (o->op_private & OPpHUSH_VMSISH) sv_catpv(tmpsv, ",HUSH_VMSISH"); } - else if (PL_check[o->op_type] != MEMBER_TO_FPTR(Perl_ck_ftst)) { + else if (PL_check[optype] != MEMBER_TO_FPTR(Perl_ck_ftst)) { if (OP_IS_FILETEST_ACCESS(o) && o->op_private & OPpFT_ACCESS) sv_catpv(tmpsv, ",FT_ACCESS"); if (o->op_private & OPpFT_STACKED) @@ -771,7 +859,7 @@ Perl_do_op_dump(pTHX_ I32 level, PerlIO *file, const OP *o) #ifdef PERL_MAD if (PL_madskills && o->op_madprop) { - SV *tmpsv = newSVpvn("", 0); + SV * const tmpsv = newSVpvn("", 0); MADPROP* mp = o->op_madprop; Perl_dump_indent(aTHX_ level, file, "MADPROPS = {\n"); level++; @@ -812,7 +900,7 @@ Perl_do_op_dump(pTHX_ I32 level, PerlIO *file, const OP *o) } #endif - switch (o->op_type) { + switch (optype) { case OP_AELEMFAST: case OP_GVSV: case OP_GV: @@ -821,7 +909,7 @@ Perl_do_op_dump(pTHX_ I32 level, PerlIO *file, const OP *o) #else if ( ! PL_op->op_flags & OPf_SPECIAL) { /* not lexical */ if (cSVOPo->op_sv) { - SV *tmpsv = newSV(0); + SV * const tmpsv = newSV(0); ENTER; SAVEFREESV(tmpsv); #ifdef PERL_MAD @@ -959,6 +1047,7 @@ static const struct { const char type; const char *name; } magic_names[] = { { PERL_MAGIC_bm, "bm(B)" }, { PERL_MAGIC_regdata, "regdata(D)" }, { PERL_MAGIC_env, "env(E)" }, + { PERL_MAGIC_hints, "hints(H)" }, { PERL_MAGIC_isa, "isa(I)" }, { PERL_MAGIC_dbfile, "dbfile(L)" }, { PERL_MAGIC_shared, "shared(N)" }, @@ -971,6 +1060,7 @@ static const struct { const char type; const char *name; } magic_names[] = { { PERL_MAGIC_envelem, "envelem(e)" }, { PERL_MAGIC_fm, "fm(f)" }, { PERL_MAGIC_regex_global, "regex_global(g)" }, + { PERL_MAGIC_hintselem, "hintselem(h)" }, { PERL_MAGIC_isaelem, "isaelem(i)" }, { PERL_MAGIC_nkeys, "nkeys(k)" }, { PERL_MAGIC_dbline, "dbline(l)" }, @@ -990,7 +1080,7 @@ static const struct { const char type; const char *name; } magic_names[] = { { PERL_MAGIC_defelem, "defelem(y)" }, { PERL_MAGIC_ext, "ext(~)" }, /* this null string terminates the list */ - { 0, 0 }, + { 0, NULL }, }; void @@ -1001,7 +1091,7 @@ Perl_do_magic_dump(pTHX_ I32 level, PerlIO *file, const MAGIC *mg, I32 nest, I32 " MAGIC = 0x%"UVxf"\n", PTR2UV(mg)); if (mg->mg_virtual) { const MGVTBL * const v = mg->mg_virtual; - const char *s = NULL; + const char *s; if (v == &PL_vtbl_sv) s = "sv"; else if (v == &PL_vtbl_env) s = "env"; else if (v == &PL_vtbl_envelem) s = "envelem"; @@ -1030,6 +1120,8 @@ Perl_do_magic_dump(pTHX_ I32 level, PerlIO *file, const MAGIC *mg, I32 nest, I32 else if (v == &PL_vtbl_backref) s = "backref"; else if (v == &PL_vtbl_utf8) s = "utf8"; else if (v == &PL_vtbl_arylen_p) s = "arylen_p"; + else if (v == &PL_vtbl_hintselem) s = "hintselem"; + else s = NULL; if (s) Perl_dump_indent(aTHX_ level, file, " MG_VIRTUAL = &PL_vtbl_%s\n", s); else @@ -1114,7 +1206,7 @@ Perl_do_magic_dump(pTHX_ I32 level, PerlIO *file, const MAGIC *mg, I32 nest, I32 void Perl_magic_dump(pTHX_ const MAGIC *mg) { - do_magic_dump(0, Perl_debug_log, mg, 0, 0, 0, 0); + do_magic_dump(0, Perl_debug_log, mg, 0, 0, FALSE, 0); } void @@ -1196,8 +1288,7 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo if (flags & SVf_FAKE) sv_catpv(d, "FAKE,"); if (flags & SVf_READONLY) sv_catpv(d, "READONLY,"); - if (flags & SVf_AMAGIC && type != SVt_PVHV) - sv_catpv(d, "OVERLOAD,"); + if (flags & SVf_AMAGIC) sv_catpv(d, "OVERLOAD,"); if (flags & SVp_IOK) sv_catpv(d, "pIOK,"); if (flags & SVp_NOK) sv_catpv(d, "pNOK,"); if (flags & SVp_POK) sv_catpv(d, "pPOK,"); @@ -1227,15 +1318,19 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo if (HvREHASH(sv)) sv_catpv(d, "REHASH,"); if (flags & SVphv_CLONEABLE) sv_catpv(d, "CLONEABLE,"); break; - case SVt_PVGV: case SVt_PVLV: - if (GvINTRO(sv)) sv_catpv(d, "INTRO,"); - if (GvMULTI(sv)) sv_catpv(d, "MULTI,"); - if (GvUNIQUE(sv)) sv_catpv(d, "UNIQUE,"); - if (GvASSUMECV(sv)) sv_catpv(d, "ASSUMECV,"); - if (GvIN_PAD(sv)) sv_catpv(d, "IN_PAD,"); + case SVt_PVGV: + case SVt_PVLV: + if (isGV_with_GP(sv)) { + if (GvINTRO(sv)) sv_catpv(d, "INTRO,"); + if (GvMULTI(sv)) sv_catpv(d, "MULTI,"); + if (GvUNIQUE(sv)) sv_catpv(d, "UNIQUE,"); + if (GvASSUMECV(sv)) sv_catpv(d, "ASSUMECV,"); + if (GvIN_PAD(sv)) sv_catpv(d, "IN_PAD,"); + } if (SvPAD_OUR(sv)) sv_catpv(d, "OUR,"); + if (SvPAD_STATE(sv)) sv_catpv(d, "STATE,"); if (SvPAD_TYPED(sv)) sv_catpv(d, "TYPED,"); - if (GvIMPORTED(sv)) { + if (isGV_with_GP(sv) && GvIMPORTED(sv)) { sv_catpv(d, "IMPORT"); if (GvIMPORTED(sv) == GVf_IMPORTED) sv_catpv(d, "ALL,"); @@ -1434,7 +1529,7 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo if (HvARRAY(sv) && HvKEYS(sv)) { /* Show distribution of HEs in the ARRAY */ int freq[200]; -#define FREQ_MAX (sizeof freq / sizeof freq[0] - 1) +#define FREQ_MAX ((int)(sizeof freq / sizeof freq[0] - 1)) int i; int max = 0; U32 pow2 = 2, keys = HvKEYS(sv); @@ -1491,18 +1586,18 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo Perl_dump_indent(aTHX_ level, file, " RITER = %"IVdf"\n", (IV)HvRITER_get(sv)); Perl_dump_indent(aTHX_ level, file, " EITER = 0x%"UVxf"\n", PTR2UV(HvEITER_get(sv))); { - MAGIC *mg = mg_find(sv, PERL_MAGIC_symtab); + MAGIC * const mg = mg_find(sv, PERL_MAGIC_symtab); if (mg && mg->mg_obj) { Perl_dump_indent(aTHX_ level, file, " PMROOT = 0x%"UVxf"\n", PTR2UV(mg->mg_obj)); } } { - const char *hvname = HvNAME_get(sv); + const char * const hvname = HvNAME_get(sv); if (hvname) Perl_dump_indent(aTHX_ level, file, " NAME = \"%s\"\n", hvname); } if (SvOOK(sv)) { - AV *backrefs = *Perl_hv_backreferences_p(aTHX_ (HV*)sv); + const AV * const backrefs = *Perl_hv_backreferences_p(aTHX_ (HV*)sv); if (backrefs) { Perl_dump_indent(aTHX_ level, file, " BACKREFS = 0x%"UVxf"\n", PTR2UV(backrefs)); @@ -1538,8 +1633,12 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo } break; case SVt_PVCV: - if (SvPOK(sv)) - Perl_dump_indent(aTHX_ level, file, " PROTOTYPE = \"%s\"\n", SvPV_nolen_const(sv)); + if (SvPOK(sv)) { + STRLEN len; + const char *const proto = SvPV_const(sv, len); + Perl_dump_indent(aTHX_ level, file, " PROTOTYPE = \"%.*s\"\n", + (int) len, proto); + } /* FALL THROUGH */ case SVt_PVFM: do_hv_dump(level, file, " COMP_STASH", CvSTASH(sv)); @@ -1583,7 +1682,7 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo do_dump_pad(level+1, file, CvPADLIST(sv), 0); } { - const CV *outside = CvOUTSIDE(sv); + const CV * const outside = CvOUTSIDE(sv); Perl_dump_indent(aTHX_ level, file, " OUTSIDE = 0x%"UVxf" (%s)\n", PTR2UV(outside), (!outside ? "null" @@ -1595,21 +1694,22 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo if (nest < maxnest && (CvCLONE(sv) || CvCLONED(sv))) do_sv_dump(level+1, file, (SV*)CvOUTSIDE(sv), nest+1, maxnest, dumpops, pvlim); break; - case SVt_PVGV: case SVt_PVLV: - if (type == SVt_PVLV) { - Perl_dump_indent(aTHX_ level, file, " TYPE = %c\n", LvTYPE(sv)); - Perl_dump_indent(aTHX_ level, file, " TARGOFF = %"IVdf"\n", (IV)LvTARGOFF(sv)); - Perl_dump_indent(aTHX_ level, file, " TARGLEN = %"IVdf"\n", (IV)LvTARGLEN(sv)); - Perl_dump_indent(aTHX_ level, file, " TARG = 0x%"UVxf"\n", PTR2UV(LvTARG(sv))); - if (LvTYPE(sv) != 't' && LvTYPE(sv) != 'T') - do_sv_dump(level+1, file, LvTARG(sv), nest+1, maxnest, - dumpops, pvlim); - } + case SVt_PVGV: + case SVt_PVLV: + if (type == SVt_PVLV) { + Perl_dump_indent(aTHX_ level, file, " TYPE = %c\n", LvTYPE(sv)); + Perl_dump_indent(aTHX_ level, file, " TARGOFF = %"IVdf"\n", (IV)LvTARGOFF(sv)); + Perl_dump_indent(aTHX_ level, file, " TARGLEN = %"IVdf"\n", (IV)LvTARGLEN(sv)); + Perl_dump_indent(aTHX_ level, file, " TARG = 0x%"UVxf"\n", PTR2UV(LvTARG(sv))); + if (LvTYPE(sv) != 't' && LvTYPE(sv) != 'T') + do_sv_dump(level+1, file, LvTARG(sv), nest+1, maxnest, + dumpops, pvlim); + } + if (!isGV_with_GP(sv)) + break; Perl_dump_indent(aTHX_ level, file, " NAME = \"%s\"\n", GvNAME(sv)); Perl_dump_indent(aTHX_ level, file, " NAMELEN = %"IVdf"\n", (IV)GvNAMELEN(sv)); do_hv_dump (level, file, " GvSTASH", GvSTASH(sv)); - if (!isGV_with_GP(sv)) - break; Perl_dump_indent(aTHX_ level, file, " GP = 0x%"UVxf"\n", PTR2UV(GvGP(sv))); if (!GvGP(sv)) break; @@ -1636,13 +1736,36 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo Perl_dump_indent(aTHX_ level, file, " LINES_LEFT = %"IVdf"\n", (IV)IoLINES_LEFT(sv)); if (IoTOP_NAME(sv)) Perl_dump_indent(aTHX_ level, file, " TOP_NAME = \"%s\"\n", IoTOP_NAME(sv)); - do_gv_dump (level, file, " TOP_GV", IoTOP_GV(sv)); + if (!IoTOP_GV(sv) || SvTYPE(IoTOP_GV(sv)) == SVt_PVGV) + do_gv_dump (level, file, " TOP_GV", IoTOP_GV(sv)); + else { + Perl_dump_indent(aTHX_ level, file, " TOP_GV = 0x%"UVxf"\n", + PTR2UV(IoTOP_GV(sv))); + do_sv_dump (level+1, file, (SV *) IoTOP_GV(sv), nest+1, maxnest, + dumpops, pvlim); + } + /* Source filters hide things that are not GVs in these three, so let's + be careful out there. */ if (IoFMT_NAME(sv)) Perl_dump_indent(aTHX_ level, file, " FMT_NAME = \"%s\"\n", IoFMT_NAME(sv)); - do_gv_dump (level, file, " FMT_GV", IoFMT_GV(sv)); + if (!IoFMT_GV(sv) || SvTYPE(IoFMT_GV(sv)) == SVt_PVGV) + do_gv_dump (level, file, " FMT_GV", IoFMT_GV(sv)); + else { + Perl_dump_indent(aTHX_ level, file, " FMT_GV = 0x%"UVxf"\n", + PTR2UV(IoFMT_GV(sv))); + do_sv_dump (level+1, file, (SV *) IoFMT_GV(sv), nest+1, maxnest, + dumpops, pvlim); + } if (IoBOTTOM_NAME(sv)) Perl_dump_indent(aTHX_ level, file, " BOTTOM_NAME = \"%s\"\n", IoBOTTOM_NAME(sv)); - do_gv_dump (level, file, " BOTTOM_GV", IoBOTTOM_GV(sv)); + if (!IoBOTTOM_GV(sv) || SvTYPE(IoBOTTOM_GV(sv)) == SVt_PVGV) + do_gv_dump (level, file, " BOTTOM_GV", IoBOTTOM_GV(sv)); + else { + Perl_dump_indent(aTHX_ level, file, " BOTTOM_GV = 0x%"UVxf"\n", + PTR2UV(IoBOTTOM_GV(sv))); + do_sv_dump (level+1, file, (SV *) IoBOTTOM_GV(sv), nest+1, maxnest, + dumpops, pvlim); + } Perl_dump_indent(aTHX_ level, file, " SUBPROCESS = %"IVdf"\n", (IV)IoSUBPROCESS(sv)); if (isPRINT(IoTYPE(sv))) Perl_dump_indent(aTHX_ level, file, " TYPE = '%c'\n", IoTYPE(sv)); @@ -1675,7 +1798,7 @@ Perl_runops_debug(pTHX) do { PERL_ASYNC_CHECK(); if (PL_debug) { - if (PL_watchaddr != 0 && *PL_watchaddr != PL_watchok) + if (PL_watchaddr && (*PL_watchaddr != PL_watchok)) PerlIO_printf(Perl_debug_log, "WARNING: %"UVxf" changed from %"UVxf" to %"UVxf"\n", PTR2UV(PL_watchaddr), PTR2UV(PL_watchok), @@ -1715,7 +1838,7 @@ Perl_debop(pTHX_ const OP *o) case OP_GVSV: case OP_GV: if (cGVOPo_gv) { - SV *sv = newSV(0); + SV * const sv = newSV(0); #ifdef PERL_MAD /* FIXME - it this making unwarranted assumptions about the UTF-8 cleanliness of the dump file handle? */ @@ -1733,18 +1856,18 @@ Perl_debop(pTHX_ const OP *o) case OP_PADHV: { /* print the lexical's name */ - CV *cv = deb_curcv(cxstack_ix); + CV * const cv = deb_curcv(cxstack_ix); SV *sv; if (cv) { - AV * const padlist = CvPADLIST(cv); + AV * const padlist = CvPADLIST(cv); AV * const comppad = (AV*)(*av_fetch(padlist, 0, FALSE)); sv = *av_fetch(comppad, o->op_targ, FALSE); } else sv = NULL; if (sv) - PerlIO_printf(Perl_debug_log, "(%s)", SvPV_nolen_const(sv)); + PerlIO_printf(Perl_debug_log, "(%s)", SvPV_nolen_const(sv)); else - PerlIO_printf(Perl_debug_log, "[%"UVuf"]", (UV)o->op_targ); + PerlIO_printf(Perl_debug_log, "[%"UVuf"]", (UV)o->op_targ); } break; default: @@ -1758,7 +1881,7 @@ STATIC CV* S_deb_curcv(pTHX_ I32 ix) { dVAR; - const PERL_CONTEXT *cx = &cxstack[ix]; + const PERL_CONTEXT * const cx = &cxstack[ix]; if (CxTYPE(cx) == CXt_SUB || CxTYPE(cx) == CXt_FORMAT) return cx->blk_sub.cv; else if (CxTYPE(cx) == CXt_EVAL && !CxTRYBLOCK(cx)) @@ -2231,33 +2354,7 @@ Perl_do_pmop_xmldump(pTHX_ I32 level, PerlIO *file, const PMOP *pm) else Perl_xmldump_indent(aTHX_ level, file, "pre=\"\" when=\"RUN\"\n"); if (pm->op_pmflags || (PM_GETRE(pm) && PM_GETRE(pm)->check_substr)) { - SV *tmpsv = newSVpvn("", 0); - if (pm->op_pmdynflags & PMdf_USED) - sv_catpv(tmpsv, ",USED"); - if (pm->op_pmdynflags & PMdf_TAINTED) - sv_catpv(tmpsv, ",TAINTED"); - if (pm->op_pmflags & PMf_ONCE) - sv_catpv(tmpsv, ",ONCE"); - if (PM_GETRE(pm) && PM_GETRE(pm)->check_substr - && !(PM_GETRE(pm)->reganch & ROPT_NOSCAN)) - sv_catpv(tmpsv, ",SCANFIRST"); - if (PM_GETRE(pm) && PM_GETRE(pm)->check_substr - && PM_GETRE(pm)->reganch & ROPT_CHECK_ALL) - sv_catpv(tmpsv, ",ALL"); - if (pm->op_pmflags & PMf_SKIPWHITE) - sv_catpv(tmpsv, ",SKIPWHITE"); - if (pm->op_pmflags & PMf_CONST) - sv_catpv(tmpsv, ",CONST"); - if (pm->op_pmflags & PMf_KEEP) - sv_catpv(tmpsv, ",KEEP"); - if (pm->op_pmflags & PMf_GLOBAL) - sv_catpv(tmpsv, ",GLOBAL"); - if (pm->op_pmflags & PMf_CONTINUE) - sv_catpv(tmpsv, ",CONTINUE"); - if (pm->op_pmflags & PMf_RETAINT) - sv_catpv(tmpsv, ",RETAINT"); - if (pm->op_pmflags & PMf_EVAL) - sv_catpv(tmpsv, ",EVAL"); + SV * const tmpsv = pm_description(pm); Perl_xmldump_indent(aTHX_ level, file, "pmflags=\"%s\"\n", SvCUR(tmpsv) ? SvPVX(tmpsv) + 1 : ""); SvREFCNT_dec(tmpsv); } @@ -2536,8 +2633,8 @@ Perl_do_op_xmldump(pTHX_ I32 level, PerlIO *file, const OP *o) S_xmldump_attr(aTHX_ level, file, "padix=\"%" IVdf "\"", (IV)cPADOPo->op_padix); #else if (cSVOPo->op_sv) { - SV *tmpsv1 = NEWSV(0,0); - SV *tmpsv2 = NEWSV(0,0); + SV *tmpsv1 = newSV(0); + SV *tmpsv2 = newSV(0); char *s; STRLEN len; SvUTF8_on(tmpsv1);