X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2Fdumpvar.pl;h=184faa39f34f66beb70ea907ae90ea9248daf292;hb=a48ec845cbd27881b821dcb9bb80e52ba093c5f2;hp=f473c45bd3fbd12d6e406db93d0b40227a2043c5;hpb=475342a6d5f74335e2bdfa64bd71f39289320205;p=p5sagit%2Fp5-mst-13.2.git diff --git a/lib/dumpvar.pl b/lib/dumpvar.pl index f473c45..184faa3 100644 --- a/lib/dumpvar.pl +++ b/lib/dumpvar.pl @@ -30,7 +30,7 @@ sub main::dumpValue { local $^W=0; (print "undef\n"), return unless defined $_[0]; (print &stringify($_[0]), "\n"), return unless ref $_[0]; - dumpvar::unwrap($_[0],0); + dumpvar::unwrap($_[0],0, $_[1]); } # This one is good for variable names: @@ -44,6 +44,12 @@ sub unctrl { $_; } +sub uniescape { + join("", + map { $_ > 255 ? sprintf("\\x{%04X}", $_) : chr($_) } + unpack("U*", $_[0])); +} + sub stringify { local($_,$noticks) = @_; local($v) ; @@ -67,6 +73,7 @@ sub stringify { } elsif ($unctrl eq 'unctrl') { s/([\"\\])/\\$1/g ; s/([\000-\037\177])/'^'.pack('c',ord($1)^64)/eg; + # uniescape? s/([\200-\377])/'\\0x'.sprintf('%2X',ord($1))/eg if $quoteHighBit; } elsif ($unctrl eq 'quote') { @@ -74,6 +81,7 @@ sub stringify { s/\033/\\e/g; s/([\000-\037\177])/'\\c'.chr(ord($1)^64)/eg; } + $_ = uniescape($_); s/([\200-\377])/'\\'.sprintf('%3o',ord($1))/eg if $quoteHighBit; ($noticks || /^\d+(\.\d*)?\Z/) ? $_ @@ -107,7 +115,7 @@ sub DumpElem { join("' '", @{$v}[0..$tArrayDepth]) . "'$shortmore"; } else { print "$short\n"; - unwrap($_[0],$_[1]); + unwrap($_[0],$_[1],$_[2]); } } @@ -115,6 +123,8 @@ sub unwrap { return if $DB::signal; local($v) = shift ; local($s) = shift ; # extra no of spaces + local($m) = shift ; # maximum recursion depth + return if $m == 0; local(%v,@v,$sp,$value,$key,@sortKeys,$more,$shortmore,$short) ; local($tHashDepth,$tArrayDepth) ; @@ -179,7 +189,7 @@ sub unwrap { return if $DB::signal; $value = $ {$v}{$key} ; print "$sp", &stringify($key), " => "; - DumpElem $value, $s; + DumpElem $value, $s, $m-1; } print "$sp empty hash\n" unless @sortKeys; print "$sp$more" if defined $more ; @@ -187,7 +197,7 @@ sub unwrap { $tArrayDepth = $#{$v} ; undef $more ; $tArrayDepth = $#{$v} < $arrayDepth-1 ? $#{$v} : $arrayDepth-1 - unless $arrayDepth eq '' ; + if defined $arrayDepth && $arrayDepth ne ''; $more = "....\n" if $tArrayDepth < $#{$v} ; $shortmore = ""; $shortmore = " ..." if $tArrayDepth < $#{$v} ; @@ -195,8 +205,8 @@ sub unwrap { if ($#$v >= 0) { $short = $sp . "0..$#{$v} " . join(" ", - map {stringify $_} @{$v}[0..$tArrayDepth]) - . "$shortmore"; + map {exists $v->[$_] ? stringify $v->[$_] : "empty"} ($[..$tArrayDepth) + ) . "$shortmore"; } else { $short = $sp . "empty array"; } @@ -209,13 +219,17 @@ sub unwrap { for $num ($[ .. $tArrayDepth) { return if $DB::signal; print "$sp$num "; - DumpElem $v->[$num], $s; + if (exists $v->[$num]) { + DumpElem $v->[$num], $s, $m-1; + } else { + print "empty slot\n"; + } } print "$sp empty array\n" unless @$v; print "$sp$more" if defined $more ; } elsif ( UNIVERSAL::isa($v, 'SCALAR') or ref $v eq 'REF' ) { print "$sp-> "; - DumpElem $$v, $s; + DumpElem $$v, $s, $m-1; } elsif ( UNIVERSAL::isa($v, 'CODE') ) { print "$sp-> "; dumpsub (0, $v); @@ -312,14 +326,27 @@ sub dumpglob { } } +sub CvGV_name_or_bust { + my $in = shift; + return if $skipCvGV; # Backdoor to avoid problems if XS broken... + $in = \&$in; # Hard reference... + eval {require Devel::Peek; 1} or return; + my $gv = Devel::Peek::CvGV($in) or return; + *$gv{PACKAGE} . '::' . *$gv{NAME}; +} + sub dumpsub { my ($off,$sub) = @_; + my $ini = $sub; + my $s; $sub = $1 if $sub =~ /^\{\*(.*)\}$/; - my $subref = \&$sub; - my $place = $DB::sub{$sub} || (($sub = $subs{"$subref"}) && $DB::sub{$sub}) - || ($subdump && ($sub = findsubs("$subref")) && $DB::sub{$sub}); + my $subref = defined $1 ? \&$sub : \&$ini; + my $place = $DB::sub{$sub} || (($s = $subs{"$subref"}) && $DB::sub{$s}) + || (($s = CvGV_name_or_bust($subref)) && $DB::sub{$s}) + || ($subdump && ($s = findsubs("$subref")) && $DB::sub{$s}); $place = '???' unless defined $place; - print( (' ' x $off) . "&$sub in $place\n" ); + $s = $sub unless defined $s; + print( (' ' x $off) . "&$s in $place\n" ); } sub findsubs { @@ -348,7 +375,9 @@ sub main::dumpvar { return if $DB::signal; next if @vars && !grep( matchvar($key, $_), @vars ); if ($usageOnly) { - globUsage(\$val, $key) unless $package eq 'dumpvar' and $key eq 'stab'; + globUsage(\$val, $key) + if ($package ne 'dumpvar' or $key ne 'stab') + and ref(\$val) eq 'GLOB'; } else { dumpglob(0,$key, $val); }