File Coverage

lib/Devel/Trepan/CmdProcessor/Frame.pm
Criterion Covered Total %
statement 18 73 24.6
branch 0 36 0.0
condition 0 7 0.0
subroutine 6 10 60.0
pod 0 4 0.0
total 24 130 18.4


line stmt bran cond sub pod time code
1             # -*- coding: utf-8 -*-
2             # Copyright (C) 2011-2012, 2014-2015 Rocky Bernstein <rocky@cpan.org>
3 12     12   83 use strict; use warnings;
  12     12   32  
  12         334  
  12         62  
  12         40  
  12         389  
4 12     12   70 use rlib '../../..';
  12         34  
  12         93  
5 12     12   4437 use Devel::Trepan::DB::LineCache; # for map_file
  12         36  
  12         2232  
6 12     12   90 use Devel::Trepan::Complete;
  12         33  
  12         1157  
7              
8             package Devel::Trepan::CmdProcessor;
9 12     12   100 use English qw( -no_match_vars );
  12         27  
  12         100  
10              
11             sub frame_complete($$;$)
12             {
13 0     0 0   my ($self, $prefix, $direction) = @_;
14 0 0         $direction = 1 unless defined $direction;
15 0           my ($low, $high) = $self->frame_low_high($direction);
16 0           my @ary = ($low..$high);
17 0           Devel::Trepan::Complete::complete_token(\@ary, $prefix);
18             }
19              
20             sub print_stack_entry()
21             {
22 0     0 0   my ($self, $frame, $i, $prefix, $opts) = @_;
23 0 0         $opts->{maxstack} = 1e9 unless defined $opts->{maxstack};
24             # Set the separator so arrays print nice.
25 0           local $LIST_SEPARATOR = ', ';
26              
27             # Get the file name.
28 0           my $file = $self->canonic_file($frame->{file});
29 0 0         $file = '??' unless defined $file;
30              
31             # Put in a filename header if short is off.
32 0 0         $file = ($file eq '-e') ? $file : "file `$file'" unless $opts->{short};
    0          
33              
34 0           my $not_last_frame = $i != ($self->{stack_size}-1);
35 0           my $s = '';
36             my $args =
37             defined $frame->{args}
38 0 0         ? "(@{ $frame->{args} })"
  0            
39             : '';
40 0 0         if ($not_last_frame) {
41             # Grab and stringify the arguments if they are there.
42              
43             # Shorten them up if $opts->{maxwidth} says they're too long.
44             $args = substr($args, 0, $opts->{maxwidth}-3) . '...'
45 0 0         if length($args) > $opts->{maxwidth};
46              
47             # Get the actual sub's name, and shorten to $maxwidth's requirement.
48 0 0         if (exists($frame->{fn})) {
49 0           $s = $frame->{fn};
50             $s = substr($s, 0, $opts->{maxwidth}-3) . '...'
51 0 0         if length($s) > $opts->{maxwidth};
52             }
53             }
54              
55             # Short report uses trimmed file and sub names.
56 0           my $want_array;
57 0 0         if (exists($frame->{wantarray})) {
58 0           $want_array = "$frame->{wantarray} = ";
59             } else {
60 0           $not_last_frame = 0;
61 0           $want_array = '' ;
62             }
63              
64 0   0       my $lineno = $frame->{line} || '??';
65 0 0 0       my $addr = $opts->{displayop} && $frame->{addr} ? sprintf("0x%x ", $frame->{addr}) : '';
66 0 0         if ($opts->{short}) {
67 0           my $fn = $s; # @_ >= 4 ? $_[3] : $s;
68 0           my $msg = sprintf("%s%s%s%s from %s:%d",
69             $want_array, $addr, $fn, $args, $file, $lineno);
70 0           $self->msg($msg);
71             } else {
72             # Non-short report includes full names.
73             # Lose the DB::DB hook call if frame is 0.
74 0 0         my $call_str = $not_last_frame ? "$addr$want_array$s$args in " : $addr;
75 0           my $prefix_call = "$prefix$call_str";
76 0           my $file_line = $file . " at line $lineno";
77              
78 0 0         if (length($prefix_call) + length($file_line) <= $opts->{maxwidth}) {
79 0           $self->msg($prefix_call . $file_line);
80             } else {
81 0           $self->msg($prefix_call);
82 0           $self->msg("\t" . $file_line);
83             }
84             }
85             }
86              
87             sub print_stack_trace_from_to($$$$$)
88             {
89 0     0 0   my ($self, $from, $to, $frames, $opts) = @_;
90 0           for (my $i=$from; $i <= $to; $i++) {
91 0 0         my $prefix = ($i == $opts->{current_pos}) ? '-->' : ' ';
92 0           $prefix .= sprintf ' #%d ', $i;
93 0           $self->print_stack_entry($frames->[$i], $i, $prefix, $opts);
94             }
95             }
96              
97             # Print `count' frame entries
98             sub print_stack_trace($$$)
99             {
100 0     0 0   my ($self, $frames, $opts)=@_;
101 0   0       $opts ||= {maxstack=>1e9, count=>1e9};
102             # $opts = DEFAULT_STACK_TRACE_SETTINGS.merge(opts);
103 0           my $halfstack = $opts->{maxstack} / 2;
104 0           my $n = scalar @{$frames};
  0            
105 0 0         $n = $opts->{count} if $opts->{count} < $n;
106 0 0         if ($n > ($halfstack * 2)) {
107 0           $self->print_stack_trace_from_to(0, $halfstack-1, $frames, $opts);
108 0           my $msg = sprintf "... %d levels ...", ($n - $halfstack*2);
109 0           $self->msg($msg);
110 0           $self->print_stack_trace_from_to($n - $halfstack, $n-1, $frames, $opts);
111             } else {
112 0           $self->print_stack_trace_from_to(0, $n-1, $frames, $opts);
113             }
114             }
115              
116             1;