File Coverage

blib/lib/Devel/MAT/Tool/Callers.pm
Criterion Covered Total %
statement 17 52 32.6
branch 0 20 0.0
condition n/a
subroutine 6 7 85.7
pod 0 1 0.0
total 23 80 28.7


line stmt bran cond sub pod time code
1             # You may distribute under the terms of either the GNU General Public License
2             # or the Artistic License (the same terms as Perl itself)
3             #
4             # (C) Paul Evans, 2017-2019 -- leonerd@leonerd.org.uk
5              
6             package Devel::MAT::Tool::Callers 0.51;
7              
8 5     5   6369 use v5.14;
  5         20  
9 5     5   234 use warnings;
  5         136  
  5         312  
10 5     5   265 use base qw( Devel::MAT::Tool );
  5         16  
  5         610  
11              
12 5     5   36 use constant CMD => "callers";
  5         9  
  5         259  
13 5     5   43 use constant CMD_DESC => "Display the caller stack";
  5         14  
  5         261  
14              
15 5         3022 use constant CMD_OPTS => (
16             pad => { help => "show PAD contents",
17             alias => "P" },
18 5     5   38 );
  5         13  
19              
20             =head1 NAME
21              
22             C - display the caller stack
23              
24             =head1 DESCRIPTION
25              
26             This C tool displays the captured state of the caller stack,
27             showing which functions have been called, and what their arguments were.
28              
29             =cut
30              
31             =head1 COMMANDS
32              
33             =head2 callers
34              
35             pmat> callers
36             caller(0): &main::func => void
37             at program.pl line 4
38             $_[0]: SCALAR(PV) at 0x55c2bdce2778 = "arguments"
39             $_[1]: SCALAR(PV) at 0x55c2bdce2868 = "go"
40             $_[2]: SCALAR(PV) at 0x55c2bdce26e8 = "here"
41              
42             Prints details of the caller stack, including arguments to functions.
43              
44             Takes the following named options:
45              
46             =over 4
47              
48             =item --pad, -P
49              
50             Additionally show the contents of the active PAD at this depth.
51              
52             =back
53              
54             =cut
55              
56             sub run
57             {
58 0     0 0   my $self = shift;
59 0           my %opts = %{ +shift };
  0            
60              
61 0           my @contexts = $self->df->contexts;
62 0           foreach my $idx ( 0 .. $#contexts ) {
63 0           my $ctx = $contexts[$idx];
64 0           my $what;
65              
66 0           for( $ctx->type ) {
67 0 0         if( $_ eq "SUB" ) {
    0          
    0          
68 0           $what = String::Tagged->from_sprintf( "%s=%s",
69             Devel::MAT::Cmd->format_sv( $ctx->cv ),
70             Devel::MAT::Cmd->format_symbol( $ctx->cv->symname ),
71             );
72             }
73             elsif( $_ eq "TRY" ) {
74 0           $what = "eval {...}";
75             }
76             elsif( $_ eq "EVAL" ) {
77 0           $what = String::Tagged->from_sprintf( "eval (%s)",
78             Devel::MAT::Cmd->format_value( $ctx->code->pv, pv => 1 ),
79             );
80             }
81             }
82              
83 0           Devel::MAT::Cmd->printf( "%s: %s => %s\n",
84             Devel::MAT::Cmd->format_note( sprintf "caller(%d)", $idx ),
85             $what,
86             Devel::MAT::Cmd->format_note( $ctx->gimme ),
87             );
88              
89 0           Devel::MAT::Cmd->printf( " at %s\n",
90             $ctx->location,
91             );
92              
93 0 0         next unless $ctx->type eq "SUB";
94              
95 0 0         my $args = $ctx->args or next;
96 0           my @args = $args->elems;
97              
98 0           my $doneargs;
99              
100             $doneargs++, Devel::MAT::Cmd->printf( " %s: %s\n",
101             Devel::MAT::Cmd->format_note( "\$_[$_]", 1 ),
102             Devel::MAT::Cmd->format_sv_with_value( $args[$_] )
103 0           ) for 0 .. $#args;
104              
105 0           my $cv = $ctx->cv;
106              
107 0           Devel::MAT::Cmd->printf( " cv=%s\n",
108             Devel::MAT::Cmd->format_sv( $cv ),
109             );
110              
111 0 0         ( my $depth = $ctx->depth ) > -1 or next;
112 0           my $pad = $cv->pad( $depth );
113              
114 0 0         if( $opts{pad} ) {
115 0           Devel::MAT::Cmd->printf( " curpad=%s\n",
116             Devel::MAT::Cmd->format_sv( $pad )
117             );
118              
119 0           require Devel::MAT::Tool::Show;
120 0           Devel::MAT::Tool::Show->show_PAD_contents( $pad );
121             }
122             else {
123 0           foreach my $name ( '$self' ) {
124 0 0         my $self_padix = $cv->padix_from_padname( $name )
125             or next;
126              
127 0 0         if( my $sv = $pad->elem( $self_padix ) ) {
128 0           $doneargs++;
129 0           Devel::MAT::Cmd->printf( " %s: %s\n",
130             Devel::MAT::Cmd->format_note( $name, 1 ),
131             Devel::MAT::Cmd->format_sv_with_value( $sv ),
132             );
133             }
134             else {
135 0           $doneargs++;
136 0           Devel::MAT::Cmd->printf( " no %s\n",
137             Devel::MAT::Cmd->format_note( $name, 1 ),
138             );
139             }
140             }
141             }
142              
143 0 0         $doneargs or
144             Devel::MAT::Cmd->printf( " %s\n",
145             Devel::MAT::Cmd->format_note( "(no args)", 1 ),
146             );
147             }
148             }
149              
150             =head1 AUTHOR
151              
152             Paul Evans
153              
154             =cut
155              
156             0x55AA;