File Coverage

lib/Devel/Trepan/WatchMgr.pm
Criterion Covered Total %
statement 75 93 80.6
branch 8 18 44.4
condition 0 4 0.0
subroutine 18 22 81.8
pod 0 13 0.0
total 101 150 67.3


line stmt bran cond sub pod time code
1             # -*- coding: utf-8 -*-
2             # Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
3 13     13   25083 use strict; use warnings; no warnings 'redefine';
  13     13   36  
  13     13   343  
  13         69  
  13         35  
  13         320  
  13         69  
  13         38  
  13         457  
4 13     13   536 use English qw( -no_match_vars );
  13         3399  
  13         81  
5 13     13   3977 use rlib '../..';
  13         34  
  13         82  
6              
7 13     13   4411 use Class::Struct;
  13         1538  
  13         157  
8 13     13   1351 use strict;
  13         36  
  13         13705  
9              
10             struct WatchPoint => {
11             id => '$', # watchpoint number
12             enabled => '$', # True if watchpoint is enabled
13             hits => '$', # How many times watch was hit
14             expr => '$', # what Perl expression to evaluate
15             old_value => '$', # Previous value
16             current_val => '$', # Current value. Set only when != old value
17             };
18              
19             package WatchPoint;
20             sub inspect($)
21             {
22 0     0   0 my $self = shift;
23 0   0     0 sprintf("watchpoint %d, expr %s, old_value: %s, current_value %s",
      0        
24             $self->id, $self->expr, $self->old_value // 'undef',
25             $self->current_val // 'undef',
26             );
27             };
28              
29             package Devel::Trepan::WatchMgr;
30              
31             sub new($$)
32             {
33 4     4 0 230 my ($class, $dbgr) = @_;
34 4         14 my $self = {};
35 4         16 $self->{dbgr} = $dbgr;
36 4         13 bless $self, $class;
37 4         23 $self->clear();
38 4         29 $self;
39             }
40              
41             sub clear($)
42             {
43 4     4 0 10 my $self = shift;
44 4         29 $self->{list} = [];
45 4         17 $self->{next_id} = 1;
46             }
47              
48             sub inspect($)
49             {
50 0     0 0 0 my $self = shift;
51 0         0 my $str = '';
52 0         0 for my $watchpoint ($self->list) {
53 0 0       0 next unless defined $watchpoint;
54 0         0 $str .= $watchpoint->inspect . "\n";
55             }
56 0         0 $str;
57             }
58              
59             sub list($)
60             {
61 23     23 0 34 my $self = shift;
62 23         32 return @{$self->{list}};
  23         78  
63            
64             }
65              
66             # Remove all breakpoints that we have recorded
67             sub DESTROY() {
68 1     1   106 my $self = shift;
69 1         4 for my $id ($self->list) {
70 1 50       5 $self->delete_by_object($id) if defined($id);
71             }
72 1         34 $self->{clear};
73             }
74              
75             sub find($$)
76             {
77 1     1 0 4 my ($self, $index) = @_;
78 1         4 for my $object ($self->list) {
79 1 50       4 next unless $object;
80 1 50       18 return $object if $object->id eq $index;
81             }
82 0         0 return undef;
83             }
84              
85             sub delete($$)
86             {
87 1     1 0 3 my ($self, $index) = @_;
88 1         3 my $object = $self->find($index);
89 1 50       15 if (defined ($object)) {
90 1         5 $self->delete_by_object($object);
91 1         9 return $object;
92             } else {
93 0         0 return undef;
94             }
95             }
96              
97             sub delete_by_object($$)
98             {
99 3     3 0 8 my ($self, $delete_object) = @_;
100 3         7 my @list = $self->list;
101 3         7 my $i = 0;
102 3         6 for my $candidate (@list) {
103 3 50       9 next unless defined $candidate;
104 3 50       15 if ($candidate eq $delete_object) {
105 3         6 splice @list, $i, 1;
106 3         6 $self->{list} = \@list;
107 3         11 return $delete_object;
108             }
109             }
110 0         0 return undef;
111             }
112              
113             sub add($$)
114             {
115 3     3 0 9 my ($self, $expr) = @_;
116             my $watchpoint = WatchPoint->new(
117 3         65 id => $self->{next_id}++,
118             enabled => 1,
119             hits => 0,
120             expr => $expr,
121             );
122            
123 3         161 push @{$self->{list}}, $watchpoint;
  3         9  
124 3         7 return $watchpoint;
125             }
126              
127             sub compact($)
128             {
129 6     6 0 9 my $self = shift;
130 6         11 my @new_list = ();
131 6         15 for my $watchpoint ($self->list) {
132 7 50       16 next unless defined $watchpoint;
133 7         16 push @new_list, $watchpoint;
134             }
135 6         12 $self->{list} = \@new_list;
136 6         12 return $self->{list};
137             }
138              
139             sub is_empty($)
140             {
141 0     0 0 0 my $self = shift;
142 0         0 $self->compact();
143 0         0 return scalar(0 == $self->list);
144             }
145              
146             sub max($)
147             {
148 6     6 0 12 my $self = shift;
149 6         11 my $max = 0;
150 6         17 for my $watchpoint ($self->list) {
151 7 50       157 $max = $watchpoint->id if $watchpoint->id > $max;
152             }
153 6         141 return $max;
154             }
155              
156             sub size($)
157             {
158 6     6 0 24 my $self = shift;
159 6         16 $self->compact();
160 6         13 return scalar $self->list;
161             }
162              
163             sub reset($)
164             {
165 0     0 0   my $self = shift;
166 0           for my $id ($self->list) {
167 0           $self->{dbgr}->delete_object($id);
168             }
169 0           $self->{list} = [];
170             }
171              
172              
173             unless (caller) {
174              
175             eval <<'EOE';
176             sub wp_status($$)
177             {
178             my ($watchpoints, $i) = @_;
179             printf "list size: %s\n", $watchpoints->size();
180             printf "max: %d\n", $watchpoints->max() // -1;
181             print $watchpoints->inspect();
182             print "--- ${i} ---\n";
183             }
184             EOE
185              
186             my $watchpoints = Devel::Trepan::WatchMgr->new('bogus');
187             wp_status($watchpoints, 0);
188              
189             my $watchpoint1 = $watchpoints->add('1+2');
190             wp_status($watchpoints, 1);
191             $watchpoints->add('3*4');
192             wp_status($watchpoints, 2);
193              
194             $watchpoints->delete_by_object($watchpoint1);
195             wp_status($watchpoints, 3);
196              
197             $watchpoints->add('3*4+5');
198             wp_status($watchpoints, 4);
199              
200             $watchpoints->delete(2);
201             wp_status($watchpoints, 5);
202              
203             }
204              
205             1;