X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=dump.c;h=544f9af64b5d1c8440d9c5b3b0b13591b8d909f9;hb=bb47c2333c2ccd252abbfcb3092724fb025ec682;hp=98405c6fad434a706b2aff95653221f479d015f3;hpb=3df15adcc3686bbc809ac9706048f258fd787941;p=p5sagit%2Fp5-mst-13.2.git diff --git a/dump.c b/dump.c index 98405c6..544f9af 100644 --- a/dump.c +++ b/dump.c @@ -1,7 +1,7 @@ /* dump.c * * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - * 2000, 2001, 2002, 2003, 2004, 2005, 2006, by Larry Wall and others + * 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, by Larry Wall and others * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -27,6 +27,45 @@ #include "proto.h" +static const char* const svtypenames[SVt_LAST] = { + "NULL", + "BIND", + "IV", + "NV", + "RV", + "PV", + "PVIV", + "PVNV", + "PVMG", + "PVGV", + "PVLV", + "PVAV", + "PVHV", + "PVCV", + "PVFM", + "PVIO" +}; + + +static const char* const svshorttypenames[SVt_LAST] = { + "UNDEF", + "BIND", + "IV", + "NV", + "RV", + "PV", + "PVIV", + "PVNV", + "PVMG", + "GV", + "PVLV", + "AV", + "HV", + "CV", + "FM", + "IO" +}; + #define Sequence PL_op_sequence void @@ -121,92 +160,193 @@ Perl_dump_eval(pTHX) /* -=for apidoc Apd|char*|pv_escape|NN SV *dsv|NN const char *pv|const STRLEN count|const STRLEN max|const U32 flags +=for apidoc Apd|char*|pv_escape|NN SV *dsv|NN const char const *str\ + |const STRLEN count|const STRLEN max + |STRLEN const *escaped, 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 +dsv 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. +If flags contains PERL_PV_ESCAPE_QUOTE then any double quotes in the string +will also be escaped. Normally the SV will be cleared before the escaped string is prepared, -but when PERL_PV_ESCAPE_CAT is set this will not occur. +but when PERL_PV_ESCAPE_NOCLEAR is set this will not occur. + +If PERL_PV_ESCAPE_UNI is set then the input string is treated as unicode, +if PERL_PV_ESCAPE_UNI_DETECT is set then the input string is scanned +using C to determine if it is unicode. + +If PERL_PV_ESCAPE_ALL is set then all input chars will be output +using C<\x01F1> style escapes, otherwise only chars above 255 will be +escaped using this style, other non printable chars will use octal or +common escaped patterns like C<\n>. If PERL_PV_ESCAPE_NOBACKSLASH +then all chars below 255 will be treated as printable and +will be output as literals. + +If PERL_PV_ESCAPE_FIRSTCHAR is set then only the first char of the +string will be escaped, regardles of max. If the string is utf8 and +the chars value is >255 then it will be returned as a plain hex +sequence. Thus the output will either be a single char, +an octal escape sequence, a special escape like C<\n> or a 3 or +more digit hex value. -Returns a pointer to the string contained by SV. +If PERL_PV_ESCAPE_RE is set then the escape char used will be a '%' and +not a '\\'. This is because regexes very often contain backslashed +sequences, whereas '%' is not a particularly common character in patterns. + +Returns a pointer to the escaped text as held by dsv. =cut */ +#define PV_ESCAPE_OCTBUFSIZE 32 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 +Perl_pv_escape( pTHX_ SV *dsv, char const * const str, + const STRLEN count, const STRLEN max, + STRLEN * const escaped, const U32 flags ) +{ + char esc = (flags & PERL_PV_ESCAPE_RE) ? '%' : '\\'; + char dq = (flags & PERL_PV_ESCAPE_QUOTE) ? '"' : esc; + char octbuf[PV_ESCAPE_OCTBUFSIZE] = "%123456789ABCDF"; + STRLEN wrote = 0; /* chars written so far */ + STRLEN chsize = 0; /* size of data to be written */ + STRLEN readsize = 1; /* size of data just read */ + bool isuni= flags & PERL_PV_ESCAPE_UNI ? 1 : 0; /* is this unicode */ + const char *pv = str; + const char *end = pv + count; /* end of string */ + octbuf[0] = esc; + + if (!flags & PERL_PV_ESCAPE_NOCLEAR) 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; + + if ((flags & PERL_PV_ESCAPE_UNI_DETECT) && is_utf8_string((U8*)pv, count)) + isuni = 1; + + for ( ; (pv < end && (!max || (wrote < max))) ; pv += readsize ) { + const UV u= (isuni) ? utf8_to_uvchr((U8*)pv, &readsize) : (U8)*pv; + const U8 c = (U8)u & 0xFF; + + if ( ( u > 255 ) || (flags & PERL_PV_ESCAPE_ALL)) { + if (flags & PERL_PV_ESCAPE_FIRSTCHAR) + chsize = my_snprintf( octbuf, PV_ESCAPE_OCTBUFSIZE, + "%"UVxf, u); + else + chsize = my_snprintf( octbuf, PV_ESCAPE_OCTBUFSIZE, + "%cx{%"UVxf"}", esc, u); + } else if (flags & PERL_PV_ESCAPE_NOBACKSLASH) { + chsize = 1; + } else { + if ( (c == dq) || (c == esc) || !isPRINT(c) ) { + chsize = 2; + switch (c) { + + case '\\' : /* fallthrough */ + case '%' : if ( c == esc ) { + octbuf[1] = esc; + } else { + chsize = 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 ) { + case '"' : + if ( dq == '"' ) octbuf[1] = '"'; - break; - } + else + chsize = 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; - } + if ( (pv < end) && isDIGIT((U8)*(pv+readsize)) ) + chsize = my_snprintf( octbuf, PV_ESCAPE_OCTBUFSIZE, + "%c%03o", esc, c); + else + chsize = my_snprintf( octbuf, PV_ESCAPE_OCTBUFSIZE, + "%c%o", esc, c); + } + } else { + chsize = 1; + } + } + if ( max && (wrote + chsize > max) ) { + break; + } else if (chsize > 1) { + sv_catpvn(dsv, octbuf, chsize); + wrote += chsize; } else { - sv_catpvn(dsv, pv, 1); + Perl_sv_catpvf( aTHX_ dsv, "%c", c); wrote++; } + if ( flags & PERL_PV_ESCAPE_FIRSTCHAR ) + break; } - if ( dq == '"' ) { + if (escaped != NULL) + *escaped= pv - str; + return SvPVX(dsv); +} +/* +=for apidoc Apd|char *|pv_pretty|NN SV *dsv|NN const char const *str\ + |const STRLEN count|const STRLEN max\ + |const char const *start_color| const char const *end_color\ + |const U32 flags + +Converts a string into something presentable, handling escaping via +pv_escape() and supporting quoting and elipses. + +If the PERL_PV_PRETTY_QUOTE flag is set then the result will be +double quoted with any double quotes in the string escaped. Otherwise +if the PERL_PV_PRETTY_LTGT flag is set then the result be wrapped in +angle brackets. + +If the PERL_PV_PRETTY_ELIPSES flag is set and not all characters in +string were output then an elipses C<...> will be appended to the +string. Note that this happens AFTER it has been quoted. + +If start_color is non-null then it will be inserted after the opening +quote (if there is one) but before the escaped text. If end_color +is non-null then it will be inserted after the escaped text but before +any quotes or elipses. + +Returns a pointer to the prettified text as held by dsv. + +=cut +*/ + +char * +Perl_pv_pretty( pTHX_ SV *dsv, char const * const str, const STRLEN count, + const STRLEN max, char const * const start_color, char const * const end_color, + const U32 flags ) +{ + U8 dq = (flags & PERL_PV_PRETTY_QUOTE) ? '"' : '%'; + STRLEN escaped; + + if ( dq == '"' ) + sv_setpvn(dsv, "\"", 1); + else if ( flags & PERL_PV_PRETTY_LTGT ) + sv_setpvn(dsv, "<", 1); + else + sv_setpvn(dsv, "", 0); + + if ( start_color != NULL ) + Perl_sv_catpv( aTHX_ dsv, start_color); + + pv_escape( dsv, str, count, max, &escaped, flags | PERL_PV_ESCAPE_NOCLEAR ); + + if ( end_color != NULL ) + Perl_sv_catpv( aTHX_ dsv, end_color); + + if ( dq == '"' ) sv_catpvn( dsv, "\"", 1 ); - if ( pv < end ) + else if ( flags & PERL_PV_PRETTY_LTGT ) + sv_catpvn( dsv, ">", 1); + + if ( (flags & PERL_PV_PRETTY_ELIPSES) && ( escaped < count ) ) sv_catpvn( dsv, "...", 3 ); - } else if ( max && (flags & PERL_PV_ESCAPE_PADR) ) { - for ( ; wrote < max ; wrote++ ) - sv_catpvn( dsv, " ", 1 ); - } + return SvPVX(dsv); } @@ -231,7 +371,7 @@ Note that the final string may be up to 7 chars longer than pvlim. 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); + pv_pretty( dsv, pv, cur, pvlim, NULL, NULL, PERL_PV_PRETTY_DUMP); if (len > cur && pv[cur] == '\0') sv_catpvn( dsv, "\\0", 2 ); return SvPVX(dsv); @@ -243,6 +383,7 @@ Perl_sv_peek(pTHX_ SV *sv) dVAR; SV * const t = sv_newmortal(); int unref = 0; + U32 type; sv_setpvn(t, "", 0); retry: @@ -324,62 +465,18 @@ Perl_sv_peek(pTHX_ SV *sv) sv = (SV*)SvRV(sv); goto retry; } - switch (SvTYPE(sv)) { - default: - sv_catpv(t, "FREED"); + type = SvTYPE(sv); + if (type == SVt_PVCV) { + Perl_sv_catpvf(aTHX_ t, "CV(%s)", CvGV(sv) ? GvNAME(CvGV(sv)) : ""); goto finish; + } else if (type < SVt_LAST) { + sv_catpv(t, svshorttypenames[type]); - case SVt_NULL: - sv_catpv(t, "UNDEF"); - goto finish; - case SVt_IV: - sv_catpv(t, "IV"); - break; - case SVt_NV: - sv_catpv(t, "NV"); - break; - case SVt_RV: - sv_catpv(t, "RV"); - break; - case SVt_PV: - sv_catpv(t, "PV"); - break; - case SVt_PVIV: - sv_catpv(t, "PVIV"); - break; - case SVt_PVNV: - sv_catpv(t, "PVNV"); - break; - case SVt_PVMG: - sv_catpv(t, "PVMG"); - break; - case SVt_PVLV: - sv_catpv(t, "PVLV"); - break; - case SVt_PVAV: - sv_catpv(t, "AV"); - break; - case SVt_PVHV: - sv_catpv(t, "HV"); - break; - case SVt_PVCV: - if (CvGV(sv)) - Perl_sv_catpvf(aTHX_ t, "CV(%s)", GvNAME(CvGV(sv))); - else - sv_catpv(t, "CV()"); + if (type == SVt_NULL) + goto finish; + } else { + sv_catpv(t, "FREED"); goto finish; - case SVt_PVGV: - sv_catpv(t, "GV"); - break; - case SVt_PVBM: - sv_catpv(t, "BM"); - break; - case SVt_PVFM: - sv_catpv(t, "FM"); - break; - case SVt_PVIO: - sv_catpv(t, "IO"); - break; } if (SvPOKp(sv)) { @@ -469,9 +566,9 @@ S_pm_description(pTHX_ const PMOP *pm) if (pmflags & PMf_ONCE) sv_catpv(desc, ",ONCE"); if (regex && regex->check_substr) { - if (!(regex->reganch & ROPT_NOSCAN)) + if (!(regex->extflags & RXf_NOSCAN)) sv_catpv(desc, ",SCANFIRST"); - if (regex->reganch & ROPT_CHECK_ALL) + if (regex->extflags & RXf_CHECK_ALL) sv_catpv(desc, ",ALL"); } if (pmflags & PMf_SKIPWHITE) @@ -623,14 +720,14 @@ Perl_do_op_dump(pTHX_ I32 level, PerlIO *file, const OP *o) level++; seq = sequence_num(o); if (seq) - PerlIO_printf(file, "%-4"UVf, seq); + PerlIO_printf(file, "%-4"UVuf, seq); else PerlIO_printf(file, " "); PerlIO_printf(file, "%*sTYPE = %s ===> ", (int)(PL_dumpindent*level-4), "", OP_NAME(o)); if (o->op_next) - PerlIO_printf(file, seq ? "%"UVf"\n" : "(%"UVf")\n", + PerlIO_printf(file, seq ? "%"UVuf"\n" : "(%"UVuf")\n", sequence_num(o->op_next)); else PerlIO_printf(file, "DONE\n"); @@ -639,7 +736,7 @@ Perl_do_op_dump(pTHX_ I32 level, PerlIO *file, const OP *o) Perl_dump_indent(aTHX_ level, file, " (was %s)\n", PL_op_name[o->op_targ]); if (o->op_targ == OP_NEXTSTATE) { if (CopLINE(cCOPo)) - Perl_dump_indent(aTHX_ level, file, "LINE = %"UVf"\n", + Perl_dump_indent(aTHX_ level, file, "LINE = %"UVuf"\n", (UV)CopLINE(cCOPo)); if (CopSTASHPV(cCOPo)) Perl_dump_indent(aTHX_ level, file, "PACKAGE = \"%s\"\n", @@ -655,7 +752,7 @@ Perl_do_op_dump(pTHX_ I32 level, PerlIO *file, const OP *o) #ifdef DUMPADDR Perl_dump_indent(aTHX_ level, file, "ADDR = 0x%"UVxf" => 0x%"UVxf"\n", (UV)o, (UV)o->op_next); #endif - if (o->op_flags) { + if (o->op_flags || o->op_latefree || o->op_latefreed || o->op_attached) { SV * const tmpsv = newSVpvs(""); switch (o->op_flags & OPf_WANT) { case OPf_WANT_VOID: @@ -683,6 +780,12 @@ Perl_do_op_dump(pTHX_ I32 level, PerlIO *file, const OP *o) sv_catpv(tmpsv, ",MOD"); if (o->op_flags & OPf_SPECIAL) sv_catpv(tmpsv, ",SPECIAL"); + if (o->op_latefree) + sv_catpv(tmpsv, ",LATEFREE"); + if (o->op_latefreed) + sv_catpv(tmpsv, ",LATEFREED"); + if (o->op_attached) + sv_catpv(tmpsv, ",ATTACHED"); Perl_dump_indent(aTHX_ level, file, "FLAGS = (%s)\n", SvCUR(tmpsv) ? SvPVX_const(tmpsv) + 1 : ""); SvREFCNT_dec(tmpsv); } @@ -820,10 +923,6 @@ Perl_do_op_dump(pTHX_ I32 level, PerlIO *file, const OP *o) if (o->op_private & OPpSORT_REVERSE) sv_catpv(tmpsv, ",REVERSE"); } - else if (optype == OP_THREADSV) { - if (o->op_private & OPpDONE_SVREF) - sv_catpv(tmpsv, ",SVREF"); - } else if (optype == OP_OPEN || optype == OP_BACKTICK) { if (o->op_private & OPpOPEN_IN_RAW) sv_catpv(tmpsv, ",IN_RAW"); @@ -913,7 +1012,7 @@ Perl_do_op_dump(pTHX_ I32 level, PerlIO *file, const OP *o) ENTER; SAVEFREESV(tmpsv); #ifdef PERL_MAD - /* FIXME - it this making unwarranted assumptions about the + /* FIXME - is this making unwarranted assumptions about the UTF-8 cleanliness of the dump file handle? */ SvUTF8_on(tmpsv); #endif @@ -939,7 +1038,7 @@ Perl_do_op_dump(pTHX_ I32 level, PerlIO *file, const OP *o) case OP_NEXTSTATE: case OP_DBSTATE: if (CopLINE(cCOPo)) - Perl_dump_indent(aTHX_ level, file, "LINE = %"UVf"\n", + Perl_dump_indent(aTHX_ level, file, "LINE = %"UVuf"\n", (UV)CopLINE(cCOPo)); if (CopSTASHPV(cCOPo)) Perl_dump_indent(aTHX_ level, file, "PACKAGE = \"%s\"\n", @@ -951,17 +1050,17 @@ Perl_do_op_dump(pTHX_ I32 level, PerlIO *file, const OP *o) case OP_ENTERLOOP: Perl_dump_indent(aTHX_ level, file, "REDO ===> "); if (cLOOPo->op_redoop) - PerlIO_printf(file, "%"UVf"\n", sequence_num(cLOOPo->op_redoop)); + PerlIO_printf(file, "%"UVuf"\n", sequence_num(cLOOPo->op_redoop)); else PerlIO_printf(file, "DONE\n"); Perl_dump_indent(aTHX_ level, file, "NEXT ===> "); if (cLOOPo->op_nextop) - PerlIO_printf(file, "%"UVf"\n", sequence_num(cLOOPo->op_nextop)); + PerlIO_printf(file, "%"UVuf"\n", sequence_num(cLOOPo->op_nextop)); else PerlIO_printf(file, "DONE\n"); Perl_dump_indent(aTHX_ level, file, "LAST ===> "); if (cLOOPo->op_lastop) - PerlIO_printf(file, "%"UVf"\n", sequence_num(cLOOPo->op_lastop)); + PerlIO_printf(file, "%"UVuf"\n", sequence_num(cLOOPo->op_lastop)); else PerlIO_printf(file, "DONE\n"); break; @@ -973,7 +1072,7 @@ Perl_do_op_dump(pTHX_ I32 level, PerlIO *file, const OP *o) case OP_AND: Perl_dump_indent(aTHX_ level, file, "OTHER ===> "); if (cLOGOPo->op_other) - PerlIO_printf(file, "%"UVf"\n", sequence_num(cLOGOPo->op_other)); + PerlIO_printf(file, "%"UVuf"\n", sequence_num(cLOGOPo->op_other)); else PerlIO_printf(file, "DONE\n"); break; @@ -1164,8 +1263,21 @@ Perl_do_magic_dump(pTHX_ I32 level, PerlIO *file, const MAGIC *mg, I32 nest, I32 Perl_dump_indent(aTHX_ level, file, " MINMATCH\n"); } if (mg->mg_obj) { - Perl_dump_indent(aTHX_ level, file, " MG_OBJ = 0x%"UVxf"\n", PTR2UV(mg->mg_obj)); - if (mg->mg_flags & MGf_REFCOUNTED) + Perl_dump_indent(aTHX_ level, file, " MG_OBJ = 0x%"UVxf"\n", + PTR2UV(mg->mg_obj)); + if (mg->mg_type == PERL_MAGIC_qr) { + regexp *re=(regexp *)mg->mg_obj; + SV *dsv= sv_newmortal(); + const char * const s = pv_pretty(dsv, re->wrapped, re->wraplen, + 60, NULL, NULL, + ( PERL_PV_PRETTY_QUOTE | PERL_PV_ESCAPE_RE | PERL_PV_PRETTY_ELIPSES | + ((re->extflags & RXf_UTF8) ? PERL_PV_ESCAPE_UNI : 0)) + ); + Perl_dump_indent(aTHX_ level+1, file, " PAT = %s\n", s); + Perl_dump_indent(aTHX_ level+1, file, " REFCNT = %"IVdf"\n", + (IV)re->refcnt); + } + if (mg->mg_flags & MGf_REFCOUNTED) do_sv_dump(level+2, file, mg->mg_obj, nest+1, maxnest, dumpops, pvlim); /* MG is already +1 */ } if (mg->mg_len) @@ -1268,9 +1380,13 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo (int)(PL_dumpindent*level), "", (IV)SvREFCNT(sv), (int)(PL_dumpindent*level), ""); - if (flags & SVs_PADSTALE) sv_catpv(d, "PADSTALE,"); - if (flags & SVs_PADTMP) sv_catpv(d, "PADTMP,"); - if (flags & SVs_PADMY) sv_catpv(d, "PADMY,"); + if (!(flags & SVpad_NAME && (type == SVt_PVMG || type == SVt_PVNV))) { + if (flags & SVs_PADSTALE) sv_catpv(d, "PADSTALE,"); + } + if (!(flags & SVpad_NAME && type == SVt_PVMG)) { + if (flags & SVs_PADTMP) sv_catpv(d, "PADTMP,"); + if (flags & SVs_PADMY) sv_catpv(d, "PADMY,"); + } if (flags & SVs_TEMP) sv_catpv(d, "TEMP,"); if (flags & SVs_OBJECT) sv_catpv(d, "OBJECT,"); if (flags & SVs_GMG) sv_catpv(d, "GMG,"); @@ -1287,13 +1403,18 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo if (flags & SVf_OOK) sv_catpv(d, "OOK,"); if (flags & SVf_FAKE) sv_catpv(d, "FAKE,"); if (flags & SVf_READONLY) sv_catpv(d, "READONLY,"); + if (flags & SVf_BREAK) sv_catpv(d, "BREAK,"); 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,"); - if (flags & SVp_SCREAM && type != SVt_PVHV) + if (flags & SVp_SCREAM && type != SVt_PVHV && !isGV_with_GP(sv)) { + if (SvPCS_IMPORTED(sv)) + sv_catpv(d, "PCS_IMPORTED,"); + else sv_catpv(d, "SCREAM,"); + } switch (type) { case SVt_PVCV: @@ -1327,9 +1448,6 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo 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 (isGV_with_GP(sv) && GvIMPORTED(sv)) { sv_catpv(d, "IMPORT"); if (GvIMPORTED(sv) == GVf_IMPORTED) @@ -1343,18 +1461,21 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo sv_catpv(d, " ),"); } } + if (SvTAIL(sv)) sv_catpv(d, "TAIL,"); + if (SvVALID(sv)) sv_catpv(d, "VALID,"); /* FALL THROUGH */ default: + evaled_or_uv: if (SvEVALED(sv)) sv_catpv(d, "EVALED,"); if (SvIsUV(sv) && !(flags & SVf_ROK)) sv_catpv(d, "IsUV,"); break; - case SVt_PVBM: - if (SvTAIL(sv)) sv_catpv(d, "TAIL,"); - if (SvVALID(sv)) sv_catpv(d, "VALID,"); - break; case SVt_PVMG: if (SvPAD_TYPED(sv)) sv_catpv(d, "TYPED,"); - break; + if (SvPAD_OUR(sv)) sv_catpv(d, "OUR,"); + /* FALL THROUGH */ + case SVt_PVNV: + if (SvPAD_STATE(sv)) sv_catpv(d, "STATE,"); + goto evaled_or_uv; case SVt_PVAV: break; } @@ -1378,57 +1499,14 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo sv->sv_debug_cloned ? " (cloned)" : ""); #endif Perl_dump_indent(aTHX_ level, file, "SV = "); - switch (type) { - case SVt_NULL: - PerlIO_printf(file, "NULL%s\n", s); - SvREFCNT_dec(d); - return; - case SVt_IV: - PerlIO_printf(file, "IV%s\n", s); - break; - case SVt_NV: - PerlIO_printf(file, "NV%s\n", s); - break; - case SVt_RV: - PerlIO_printf(file, "RV%s\n", s); - break; - case SVt_PV: - PerlIO_printf(file, "PV%s\n", s); - break; - case SVt_PVIV: - PerlIO_printf(file, "PVIV%s\n", s); - break; - case SVt_PVNV: - PerlIO_printf(file, "PVNV%s\n", s); - break; - case SVt_PVBM: - PerlIO_printf(file, "PVBM%s\n", s); - break; - case SVt_PVMG: - PerlIO_printf(file, "PVMG%s\n", s); - break; - case SVt_PVLV: - PerlIO_printf(file, "PVLV%s\n", s); - break; - case SVt_PVAV: - PerlIO_printf(file, "PVAV%s\n", s); - break; - case SVt_PVHV: - PerlIO_printf(file, "PVHV%s\n", s); - break; - case SVt_PVCV: - PerlIO_printf(file, "PVCV%s\n", s); - break; - case SVt_PVGV: - PerlIO_printf(file, "PVGV%s\n", s); - break; - case SVt_PVFM: - PerlIO_printf(file, "PVFM%s\n", s); - break; - case SVt_PVIO: - PerlIO_printf(file, "PVIO%s\n", s); - break; - default: + if (type < SVt_LAST) { + PerlIO_printf(file, "%s%s\n", svtypenames[type], s); + + if (type == SVt_NULL) { + SvREFCNT_dec(d); + return; + } + } else { PerlIO_printf(file, "UNKNOWN(0x%"UVxf") %s\n", (UV)type, s); SvREFCNT_dec(d); return; @@ -1454,9 +1532,15 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo #endif PerlIO_putc(file, '\n'); } - if ((type >= SVt_PVNV && type != SVt_PVAV && type != SVt_PVHV - && type != SVt_PVCV && type != SVt_PVFM && !isGV_with_GP(sv)) - || type == SVt_NV) { + if ((type == SVt_PVNV || type == SVt_PVMG) && SvFLAGS(sv) & SVpad_NAME) { + Perl_dump_indent(aTHX_ level, file, " COP_LOW = %"UVuf"\n", + (UV) COP_SEQ_RANGE_LOW(sv)); + Perl_dump_indent(aTHX_ level, file, " COP_HIGH = %"UVuf"\n", + (UV) COP_SEQ_RANGE_HIGH(sv)); + } else if ((type >= SVt_PVNV && type != SVt_PVAV && type != SVt_PVHV + && type != SVt_PVCV && type != SVt_PVFM && !isGV_with_GP(sv) + && !SvVALID(sv)) + || type == SVt_NV) { STORE_NUMERIC_LOCAL_SET_STANDARD(); /* %Vg doesn't work? --jhi */ #ifdef USE_LONG_DOUBLE @@ -1491,8 +1575,14 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo Perl_dump_indent(aTHX_ level, file, " PV = 0\n"); } if (type >= SVt_PVMG) { - if (SvMAGIC(sv)) - do_magic_dump(level, file, SvMAGIC(sv), nest, maxnest, dumpops, pvlim); + if (type == SVt_PVMG && SvPAD_OUR(sv)) { + HV *ost = SvOURSTASH(sv); + if (ost) + do_hv_dump(level, file, " OURSTASH", ost); + } else { + if (SvMAGIC(sv)) + do_magic_dump(level, file, SvMAGIC(sv), nest, maxnest, dumpops, pvlim); + } if (SvSTASH(sv)) do_hv_dump(level, file, " STASH", SvSTASH(sv)); } @@ -1705,6 +1795,12 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo do_sv_dump(level+1, file, LvTARG(sv), nest+1, maxnest, dumpops, pvlim); } + if (SvVALID(sv)) { + Perl_dump_indent(aTHX_ level, file, " FLAGS = %u\n", (U8)BmFLAGS(sv)); + Perl_dump_indent(aTHX_ level, file, " RARE = %u\n", (U8)BmRARE(sv)); + Perl_dump_indent(aTHX_ level, file, " PREVIOUS = %"UVuf"\n", (UV)BmPREVIOUS(sv)); + Perl_dump_indent(aTHX_ level, file, " USEFUL = %"IVdf"\n", (IV)BmUSEFUL(sv)); + } if (!isGV_with_GP(sv)) break; Perl_dump_indent(aTHX_ level, file, " NAME = \"%s\"\n", GvNAME(sv)); @@ -1840,7 +1936,7 @@ Perl_debop(pTHX_ const OP *o) if (cGVOPo_gv) { SV * const sv = newSV(0); #ifdef PERL_MAD - /* FIXME - it this making unwarranted assumptions about the + /* FIXME - is this making unwarranted assumptions about the UTF-8 cleanliness of the dump file handle? */ SvUTF8_on(sv); #endif @@ -2292,8 +2388,8 @@ Perl_sv_xmlpeek(pTHX_ SV *sv) case SVt_PVGV: sv_catpv(t, " GV=\""); break; - case SVt_PVBM: - sv_catpv(t, " BM=\""); + case SVt_BIND: + sv_catpv(t, " BIND=\""); break; case SVt_PVFM: sv_catpv(t, " FM=\""); @@ -2342,7 +2438,7 @@ Perl_do_pmop_xmldump(pTHX_ I32 level, PerlIO *file, const PMOP *pm) level++; if (PM_GETRE(pm)) { char *s = PM_GETRE(pm)->precomp; - SV *tmpsv = newSV(0); + SV *tmpsv = newSVpvn("",0); SvUTF8_on(tmpsv); sv_catxmlpvn(tmpsv, s, strlen(s), 1); Perl_xmldump_indent(aTHX_ level, file, "pre=\"%s\"\n", @@ -2404,7 +2500,7 @@ Perl_do_op_xmldump(pTHX_ I32 level, PerlIO *file, const OP *o) if (o->op_targ == OP_NEXTSTATE) { if (CopLINE(cCOPo)) - PerlIO_printf(file, " line=\"%"UVf"\"", + PerlIO_printf(file, " line=\"%"UVuf"\"", (UV)CopLINE(cCOPo)); if (CopSTASHPV(cCOPo)) PerlIO_printf(file, " package=\"%s\"", @@ -2585,10 +2681,6 @@ Perl_do_op_xmldump(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) { - if (o->op_private & OPpDONE_SVREF) - sv_catpv(tmpsv, ",SVREF"); - } else if (o->op_type == OP_OPEN || o->op_type == OP_BACKTICK) { if (o->op_private & OPpOPEN_IN_RAW) sv_catpv(tmpsv, ",IN_RAW"); @@ -2634,7 +2726,7 @@ Perl_do_op_xmldump(pTHX_ I32 level, PerlIO *file, const OP *o) #else if (cSVOPo->op_sv) { SV *tmpsv1 = newSV(0); - SV *tmpsv2 = newSV(0); + SV *tmpsv2 = newSVpvn("",0); char *s; STRLEN len; SvUTF8_on(tmpsv1); @@ -2671,7 +2763,7 @@ Perl_do_op_xmldump(pTHX_ I32 level, PerlIO *file, const OP *o) case OP_NEXTSTATE: case OP_DBSTATE: if (CopLINE(cCOPo)) - S_xmldump_attr(aTHX_ level, file, "line=\"%"UVf"\"", + S_xmldump_attr(aTHX_ level, file, "line=\"%"UVuf"\"", (UV)CopLINE(cCOPo)); if (CopSTASHPV(cCOPo)) S_xmldump_attr(aTHX_ level, file, "package=\"%s\"",