File Coverage

lib/Devel/Trepan/CmdProcessor/Command/Break.pm
Criterion Covered Total %
statement 110 214 51.4
branch 11 68 16.1
condition 2 12 16.6
subroutine 29 34 85.2
pod 0 6 0.0
total 152 334 45.5


line stmt bran cond sub pod time code
1             # -*- coding: utf-8 -*-
2             # Copyright (C) 2011-2014 Rocky Bernstein <rocky@cpan.org>
3 12     12   87310 use warnings; no warnings 'redefine';
  12     12   38  
  12     2   381  
  12     2   60  
  12         24  
  12         8990  
  2         15  
  2         7  
  2         53  
  2         10  
  2         4  
  2         83  
4 12     12   21556 use rlib '../../../..';
  12     2   28  
  12         107  
  2         11  
  2         4  
  2         8  
5              
6 12     12   12150 use Devel::Trepan::DB::Sub;
  12     2   34  
  12         517  
  2         639  
  2         5  
  2         124  
7             # require_relative '../../app/condition'
8              
9             package Devel::Trepan::CmdProcessor::Command::Break;
10 12     12   568 use Devel::Trepan::DB::LineCache;
  12     2   24  
  12         4307  
  2         16  
  2         3  
  2         386  
11 12     12   282 use English qw( -no_match_vars );
  12     2   24  
  12         68  
  2         22  
  2         3  
  2         13  
12 12     12   4549 use if !@ISA, Devel::Trepan::CmdProcessor::Command;
  12     2   34  
  12         75  
  2         695  
  2         14  
  2         10  
13             unless (@ISA) {
14 12     12   73 eval <<'EOE';
  12     12   28  
  12     12   631  
  12     12   92  
  12     12   36  
  12     12   593  
  12         82  
  12         25  
  12         552  
  12         80  
  12         36  
  12         580  
  12         74  
  12         19  
  12         956  
  12         121  
  12         47  
  12         544  
15             use constant ALIASES => qw(b);
16             use constant CATEGORY => 'breakpoints';
17             use constant SHORT_HELP => 'Set a breakpoint';
18             use constant MIN_ARGS => 0; # Need at least this many
19             use constant MAX_ARGS => undef; # Need at most this many - undef -> unlimited.
20             use constant NEED_STACK => 0;
21             EOE
22             }
23              
24 12     12   15863 use strict; use vars qw(@ISA); @ISA = @CMD_ISA;
  12     12   25  
  12     2   263  
  12     2   55  
  12         22  
  12         555  
  2         149  
  2         4  
  2         47  
  2         13  
  2         5  
  2         96  
25 12     12   73 use vars @CMD_VARS; # Value inherited from parent
  12     2   22  
  12         11548  
  2         10  
  2         5  
  2         1920  
26              
27             our $NAME = set_name();
28             =head2 Synopsis:
29              
30             =cut
31             our $HELP = <<'HELP';
32             =pod
33              
34             B<break> [I<location>] [B<if> I<condition>]
35              
36             Set a breakpoint. If I<location> is given use the current stopping
37             point. An optional condition may be given.
38              
39             =head2 Examples:
40              
41             break # set a breakpoint on the current line
42             break gcd # set a breakpoint in function gcd
43             break gcd if $a == 1 # set a breakpoint in function gcd with
44             # condition $a == 1
45             break 10 # set breakpoint on line 10
46              
47             When a breakpoint is hit the event icon is C<xx>.
48              
49             =head2 See also:
50              
51             C<help breakpoints>, L<C<info
52             breakpoints>|Devel::Trepan::CmdProcessor::Command::Info::Breakpoints>,
53             and L<C<help syntax location>|Devel::Trepan::CmdProcessor::Command::Help::location>.
54              
55             =cut
56             HELP
57              
58             # FIXME: Should we include all files?
59             # Combine with LIST completion.
60             sub complete($$)
61             {
62 0     0 0 0 my ($self, $prefix) = @_;
  0     0 0 0  
63 0         0 my $filename = $self->{proc}->filename;
  0         0  
64 0         0 my @completions = sort(('.', file_list, DB::subs,
  0         0  
65             trace_line_numbers($filename)));
66 0         0 Devel::Trepan::Complete::complete_token(\@completions, $prefix);
  0         0  
67             }
68              
69             # include Trepan::Condition
70              
71             # This method runs the command
72             sub run($$) {
73 3     3 0 1674 my ($self, $args) = @_;
  0     0 0    
74 3         8 my @args = @$args;
  0            
75 3         6 shift @args;
  0            
76 3         9 my $proc = $self->{proc};
  0            
77 3         4 my $bp;
  0            
78 3         6 my $arg_count = scalar @args;
  0            
79 3 100       8 if ($arg_count == 0) {
  0 0          
80 1         5 $bp = $self->{dbgr}->set_break($DB::filename, $DB::lineno);
  0            
81             } else {
82 2         5 my ($filename, $line_or_fn, $condition);
  0            
83 2 50       4 if ($arg_count > 2) {
  0 0          
84 0 0       0 if ($args[0] eq 'if') {
  0 0          
85 0         0 $line_or_fn = $DB::lineno;
  0            
86 0         0 $filename = $DB::filename;
  0            
87 0         0 unshift @args, $line_or_fn;
  0            
88             } else {
89 0         0 $filename = $args[0];
  0            
90 0 0       0 if ($args[1] =~ /\d+/) {
  0 0          
    0          
    0          
91 0         0 $line_or_fn = $args[1];
  0            
92 0         0 shift @args;
  0            
93             } elsif ($args[1] eq 'if') {
94 0         0 $line_or_fn = $args[0];
  0            
95             } else {
96 0         0 $line_or_fn = $args[0];
  0            
97             }
98             }
99             } else {
100             # $arg_count <= 2.
101 2         4 $line_or_fn = $args[0];
  0            
102 2 100       9 if ($line_or_fn =~ /^\d+/) {
  0 0          
103 1         4 $filename = $DB::filename;
  0            
104             } else {
105             # FIXME: create a subroutine and combine with Deparse.
106 1         5 my @matches = $self->{dbgr}->subs($args[0]);
  0            
107 1 50       6 if (scalar(@matches) == 1) {
  0 0          
108 1         3 $filename = $matches[0][0];
  0            
109             } else {
110 0         0 $filename = $args[0];
  0            
111 0         0 my $canonic_name = map_file($filename);
  0            
112 0 0       0 if (is_cached($canonic_name)) {
  0 0          
113 0         0 $filename = $canonic_name;
  0            
114             }
115             }
116             }
117 2 100 66     10 if ($arg_count == 2 && $args[1] =~ /\d+/) {
  0 0 0        
118 1         2 $line_or_fn = $args[1];
  0            
119 1         2 shift @args;
  0            
120             }
121             }
122 2         3 shift @args;
  0            
123 2 50       5 if (scalar @args) {
  0 0          
124 0 0       0 if ($args[0] eq 'if') {
  0 0          
125 0         0 shift @args;
  0            
126 0         0 $condition = join(' ', @args);
  0            
127             } else {
128 0         0 $proc->errmsg("Expecting 'if' to start breakpoint condition;" .
  0            
129             " got ${args[0]}");
130             }
131             }
132 2         8 my $msg = $self->{dbgr}->break_invalid(\$filename, $line_or_fn);
  0            
133 2         6 my $force = 0;
  0            
134 2 50       5 if ($msg) {
  0 0          
135 0 0       0 if ($msg =~ /not known to be a trace line/) {
  0 0          
136 0         0 $proc->errmsg($msg);
  0            
137 0         0 $proc->msg("Use 'info file $filename brkpts' to see breakpoints I know about");
  0            
138 0         0 $force = $self->{proc}->confirm('Set breakpoint anyway?', 0);
  0            
139 0 0       0 return unless $force;
  0 0          
140             }
141             }
142 2         6 $bp = $self->{dbgr}->set_break($filename, $line_or_fn,
  0            
143             $condition, undef, undef, undef, $force);
144             }
145 3 50       24 if (defined($bp)) {
  0 0          
146 0 0         my $prefix = $bp->type eq 'tbrkpt' ?
  0 0          
147             'Temporary breakpoint' : 'Breakpoint' ;
148 0           my $id = $bp->id;
  0            
149 0           my $filename = $proc->canonic_file($bp->filename);
  0            
150 0           my $line_num = $bp->line_num;
  0            
151 0           $proc->{brkpts}->add($bp);
  0            
152 0           $proc->msg("$prefix $id set in $filename at line $line_num");
  0            
153             # Warn if we are setting a breakpoint on a line that starts
154             # "use.."
155 0           my $text = getline($bp->filename, $line_num, {output => 'plain'});
  0            
156 0 0 0       if (defined($text) && $text =~ /^\s*use\s+/) {
  0 0 0        
157 0           $proc->msg("Warning: 'use' statements get evaluated at compile time... You may have already passed this statement.");
  0            
158             }
159             }
160             }
161              
162             unless (caller) {
163             # FIXME: DRY this code by putting in common location.
164             require Devel::Trepan::DB;
165             require Devel::Trepan::Core;
166             my $db = Devel::Trepan::Core->new;
167             my $intf = Devel::Trepan::Interface::User->new(undef, undef,
168             {readline => 0});
169             my $proc = Devel::Trepan::CmdProcessor->new([$intf], $db);
170             $proc->{stack_size} = 0;
171             my $cmd = __PACKAGE__->new($proc);
172              
173             eval {
174             sub db_setup() {
175 12     12   98 no warnings 'once';
  12     2   41  
  12         1730  
  2         15  
  2         4  
  2         251  
176 0     0 0   $DB::caller = [caller];
  0     0 0    
177             ($DB::package, $DB::filename, $DB::lineno, $DB::subroutine)
178 0           = @{$DB::caller};
  0            
  0            
  0            
179             }
180             };
181             db_setup();
182              
183             $cmd->run([$NAME]);
184             # $cmd->run([$NAME, "/usr/share/perl/5.14.2/File/Basename.pm", "3"]);
185             }
186              
187             1;