File Coverage

blib/lib/B/CodeLines.pm
Criterion Covered Total %
statement 9 58 15.5
branch 0 22 0.0
condition 0 9 0.0
subroutine 3 12 25.0
pod 0 4 0.0
total 12 105 11.4


line stmt bran cond sub pod time code
1             package B::CodeLines;
2             # Copyright (C) 2012 Rocky Bernstein. All rights reserved.
3             # This program is free software; you can redistribute and/or modify it
4             # under the same terms as Perl itself.
5              
6             # B::Concise was used as a guide for how to write this.
7              
8 1     1   50210 use strict; use warnings;
  1     1   2  
  1         38  
  1         4  
  1         1  
  1         118  
9              
10             our $VERSION = '1.1';
11              
12 1     1   68 use B qw(class main_start main_root main_cv OPf_KIDS walksymtable);
  1         14  
  1         1858  
13              
14             my $current_file;
15              
16             # use Enbugger;
17             sub main {
18 0     0 0   sequence(main_start);
19             # Enbugger->stop;
20 0 0         return if class(main_root) eq "NULL";
21             walk_topdown(main_root,
22 0     0     sub { $_[0]->codelines($_[1]) }, 0);
  0            
23             # print "+++1 $current_file\n";
24             # walksymtable(\%main::, 'print_subs', 1, 'B::Lines::');
25              
26             }
27              
28             sub compile {
29 0     0     return sub { main(); }
30 0     0 0   }
31              
32             sub walk_topdown {
33 0     0 0   my($op, $sub, $level) = @_;
34 0           $sub->($op, $level);
35 0 0         if ($op->flags & OPf_KIDS) {
    0          
36 0           for (my $kid = $op->first; $$kid; $kid = $kid->sibling) {
37 0           walk_topdown($kid, $sub, $level + 1);
38             }
39             }
40             elsif (class($op) eq "PMOP") {
41 0           my $maybe_root = $op->pmreplroot;
42 0 0 0       if (ref($maybe_root) and $maybe_root->isa("B::OP")) {
43             # It really is the root of the replacement, not something
44             # else stored here for lack of space elsewhere
45 0           walk_topdown($maybe_root, $sub, $level + 1);
46             }
47             }
48             }
49              
50             # The structure of this routine is purposely modeled after op.c's peep()
51             sub sequence {
52 0     0 0   my($op) = @_;
53 0           my $oldop = 0;
54 0 0         return if class($op) eq "NULL";
55 0           for (; $$op; $op = $op->next) {
56 0           my $name = $op->name;
57 0 0         if ($name =~ /^(null|scalar|lineseq|scope)$/) {
58 0 0 0       next if $oldop and $ {$op->next};
  0            
59             } else {
60 0 0 0       if (class($op) eq "LOGOP") {
    0          
    0          
61 0           my $other = $op->other;
62 0           $other = $other->next while $other->name eq "null";
63 0           sequence($other);
64 0           } elsif (class($op) eq "LOOP") {
65 0           my $redoop = $op->redoop;
66 0           $redoop = $redoop->next while $redoop->name eq "null";
67 0           sequence($redoop);
68 0           my $nextop = $op->nextop;
69 0           $nextop = $nextop->next while $nextop->name eq "null";
70 0           sequence($nextop);
71 0           my $lastop = $op->lastop;
72 0           $lastop = $lastop->next while $lastop->name eq "null";
73 0           sequence($lastop);
74             } elsif ($name eq "subst" and $ {$op->pmreplstart}) {
75 0           my $replstart = $op->pmreplstart;
76 0           $replstart = $replstart->next while $replstart->name eq "null";
77 0           sequence($replstart);
78             }
79             }
80 0           $oldop = $op;
81             }
82             }
83              
84             sub B::OP::codelines {
85 0     0     my($op) = @_;
86 0 0         if ('COP' eq class($op)) {
87 0           $current_file = $op->file;
88 0           printf "%s\n", $op->line;
89             }
90             }
91              
92             sub B::GV::print_subs
93             {
94 0     0     my($gv) = @_;
95             # Should bail if $gv->FILE ne $B::Lines::current_file.
96 0           print $gv->NAME(), " ", $gv->FILE(), "\n";
97 0           eval {
98             walk_topdown($gv->CV->START,
99 0     0     sub { $_[0]->codelines($_[1]) }, 0)
  0            
100             };
101             };
102              
103              
104             1;