line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
|
2
|
|
|
|
|
|
|
package Devel::StealthDebug; |
3
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
require Exporter; |
5
|
|
|
|
|
|
|
@ISA=qw(Exporter); |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
@EXPORT=(); # put the public function here |
8
|
|
|
|
|
|
|
@EXPORT_OK=(); # to unable a non-stealth interface |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
|
11
|
14
|
|
|
14
|
|
672019
|
use strict; |
|
14
|
|
|
|
|
38
|
|
|
14
|
|
|
|
|
495
|
|
12
|
14
|
|
|
14
|
|
74
|
use Carp; |
|
14
|
|
|
|
|
25
|
|
|
14
|
|
|
|
|
1155
|
|
13
|
14
|
|
|
14
|
|
21010
|
use Filter::Simple; |
|
14
|
|
|
|
|
429192
|
|
|
14
|
|
|
|
|
110
|
|
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
our $SOURCE = 0; |
16
|
|
|
|
|
|
|
our $VERSION = '1.008'; # Beware ! 1.1.2 sould be 1.001002 |
17
|
|
|
|
|
|
|
our $TABLEN = 2; |
18
|
|
|
|
|
|
|
our $ENABLE = 1; |
19
|
|
|
|
|
|
|
our $DUMPER = 0; |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
our $Emit = 'carp'; |
22
|
|
|
|
|
|
|
our $Counter = 1; |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
my %Wait_Cond; |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
sub import { |
27
|
|
|
|
|
|
|
shift; |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
while (my $imported = shift) { |
30
|
|
|
|
|
|
|
if ($imported eq 'SOURCE') { |
31
|
|
|
|
|
|
|
my $file = shift; |
32
|
|
|
|
|
|
|
open SOURCE,"> $file"; |
33
|
|
|
|
|
|
|
$SOURCE = 1; |
34
|
|
|
|
|
|
|
} elsif ($imported eq 'emit_type') { |
35
|
|
|
|
|
|
|
$Emit = shift; |
36
|
|
|
|
|
|
|
if ($Emit =~ m:/:) { |
37
|
|
|
|
|
|
|
my $tfh; |
38
|
|
|
|
|
|
|
open($tfh,">>$Emit") or die $!; # replace filename by filehandle. |
39
|
|
|
|
|
|
|
select($tfh);$|++; |
40
|
|
|
|
|
|
|
$Emit=$tfh; |
41
|
|
|
|
|
|
|
} |
42
|
|
|
|
|
|
|
} elsif ($imported eq 'DUMPER') { |
43
|
|
|
|
|
|
|
$DUMPER = shift ; |
44
|
|
|
|
|
|
|
} elsif ($imported eq 'ENABLE') { |
45
|
|
|
|
|
|
|
my $file_or_not = shift; |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
$ENABLE = $file_or_not; # By default assume it's a value |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
if (-e $file_or_not) { # If the file exists |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
$ENABLE = 0; # disable ENABLE |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
open INFILE,"<$file_or_not" or croak "Can't open $file_or_not ($!)"; |
54
|
|
|
|
|
|
|
while(my $authorized = ) { |
55
|
|
|
|
|
|
|
chomp $authorized; |
56
|
|
|
|
|
|
|
if ($0 =~ /$authorized/) { # unless the file allows it. |
57
|
|
|
|
|
|
|
$ENABLE = 1; # unless |
58
|
|
|
|
|
|
|
last; |
59
|
|
|
|
|
|
|
} |
60
|
|
|
|
|
|
|
} |
61
|
|
|
|
|
|
|
close INFILE; |
62
|
|
|
|
|
|
|
} |
63
|
|
|
|
|
|
|
} else { |
64
|
|
|
|
|
|
|
croak "Unknown $imported option ($imported @_)"; |
65
|
|
|
|
|
|
|
} |
66
|
|
|
|
|
|
|
} |
67
|
|
|
|
|
|
|
if ($DUMPER) { |
68
|
|
|
|
|
|
|
require Data::Dumper ; |
69
|
|
|
|
|
|
|
$Data::Dumper::Indent = 1; |
70
|
|
|
|
|
|
|
$Data::Dumper::Sortkeys = 1; |
71
|
|
|
|
|
|
|
} |
72
|
|
|
|
|
|
|
} |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
sub emit { |
75
|
9
|
100
|
|
9
|
0
|
4318
|
if ($Emit eq 'carp') { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
76
|
1
|
|
|
|
|
255
|
carp @_, ' in ' , (caller(1))[3] ; |
77
|
|
|
|
|
|
|
} elsif ($Emit eq 'croak') { |
78
|
2
|
|
|
|
|
432
|
croak @_, ' in ' , (caller(1))[3]; |
79
|
|
|
|
|
|
|
} elsif ($Emit eq 'print') { |
80
|
5
|
|
|
|
|
331
|
print @_; |
81
|
|
|
|
|
|
|
} elsif (ref $Emit =~ /CODE/) { |
82
|
0
|
|
|
|
|
0
|
&$Emit(@_); |
83
|
|
|
|
|
|
|
} else { # Otherwise it's a filehandle |
84
|
1
|
|
|
|
|
98
|
print $Emit @_; |
85
|
|
|
|
|
|
|
} |
86
|
|
|
|
|
|
|
} |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
sub emit_type { |
89
|
1
|
|
|
1
|
0
|
2
|
my $orig = shift; |
90
|
1
|
|
|
|
|
2
|
my $emit = shift; |
91
|
|
|
|
|
|
|
|
92
|
1
|
50
|
|
|
|
7
|
if ($emit =~ /(carp|croak|print)/) { |
93
|
1
|
|
|
|
|
5
|
return "\$Devel::StealthDebug::Emit = $emit;$orig" |
94
|
|
|
|
|
|
|
} |
95
|
|
|
|
|
|
|
} |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
sub add_assert { |
98
|
0
|
|
|
0
|
0
|
0
|
my $orig = shift; |
99
|
0
|
|
|
|
|
0
|
my $cond = my $cond2 = shift; |
100
|
|
|
|
|
|
|
|
101
|
0
|
|
|
|
|
0
|
$cond2 =~ s/\'/\\\'/g; |
102
|
0
|
|
|
|
|
0
|
return "die '($cond2) condition failed' if !($cond);$orig"; |
103
|
|
|
|
|
|
|
} |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
sub add_emit { |
106
|
6
|
|
|
6
|
0
|
22
|
my $orig = shift; |
107
|
6
|
|
|
|
|
15
|
my $text = shift; |
108
|
|
|
|
|
|
|
|
109
|
6
|
|
|
|
|
13
|
$text =~ s/^"(.*)"$/$1/; |
110
|
6
|
|
|
|
|
13
|
$text =~ s/\"/\\\"/g; |
111
|
6
|
|
|
|
|
42
|
return "$orig;Devel::StealthDebug::emit \"$text\";"; |
112
|
|
|
|
|
|
|
} |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
sub add_dump { |
115
|
2
|
|
|
2
|
0
|
12
|
my $orig = shift; |
116
|
2
|
|
|
|
|
5
|
my $ref = shift; |
117
|
|
|
|
|
|
|
|
118
|
2
|
|
|
|
|
3
|
$Counter++; |
119
|
|
|
|
|
|
|
|
120
|
2
|
|
|
|
|
5
|
my $output = $orig . ';$Data::Dumper::Sortkeys=1;Devel::StealthDebug::emit('; |
121
|
2
|
|
|
|
|
10
|
my @vars = split (/\s*,\s*/, $ref) ; |
122
|
2
|
|
|
|
|
4
|
my $i = 0 ; |
123
|
|
|
|
|
|
|
|
124
|
2
|
100
|
|
|
|
7
|
if ($DUMPER) { |
125
|
1
|
|
|
|
|
7
|
while ($vars[0] =~ /^\'|\"/) { |
126
|
0
|
0
|
|
|
|
0
|
$output .= (shift @vars) . (@vars?',':'') ; |
127
|
|
|
|
|
|
|
} |
128
|
1
|
|
|
|
|
15
|
$output .= 'Data::Dumper -> Dump ([' . join (',', @vars) . "],['" . join ("','", @vars) . "']));"; |
129
|
|
|
|
|
|
|
} else { |
130
|
1
|
|
|
|
|
3
|
foreach my $var (@vars) { |
131
|
1
|
50
|
|
|
|
6
|
$output .= ($i++?',':'') . "'\$$var = ', Devel::StealthDebug::dumpvalue($var,-1)"; |
132
|
|
|
|
|
|
|
} |
133
|
1
|
|
|
|
|
2
|
$output .= ');' ; |
134
|
|
|
|
|
|
|
} |
135
|
2
|
|
|
|
|
10
|
return $output ; |
136
|
|
|
|
|
|
|
} |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
sub dumpvalue { |
139
|
10
|
|
|
10
|
0
|
785
|
my $type = shift; |
140
|
10
|
|
|
|
|
16
|
my $tabn = shift; |
141
|
|
|
|
|
|
|
|
142
|
10
|
|
|
|
|
16
|
my $ref = ref $type; |
143
|
10
|
|
|
|
|
21
|
my $tab = ' ' x ($tabn+1); |
144
|
10
|
|
|
|
|
13
|
my $output; |
145
|
10
|
|
|
|
|
13
|
$tabn += $TABLEN; |
146
|
|
|
|
|
|
|
|
147
|
10
|
100
|
|
|
|
186
|
if ($type =~ /^($ref=)?HASH/) { |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
148
|
2
|
|
|
|
|
9
|
$output = "{\n".dump_hash($type,$tabn,'')."$tab},\n"; |
149
|
|
|
|
|
|
|
} elsif ($type =~ /^($ref=)?ARRAY/) { |
150
|
1
|
|
|
|
|
6
|
$output = "[\n".dump_array($type,$tabn,'')."$tab],\n"; |
151
|
|
|
|
|
|
|
} elsif ($type =~ /^($ref=)?SCALAR/) { |
152
|
0
|
|
|
|
|
0
|
$output = dump_scalar($type,$tabn,''); |
153
|
|
|
|
|
|
|
} else { |
154
|
7
|
|
|
|
|
15
|
$output = dump_scalar($type,$tabn,''); |
155
|
|
|
|
|
|
|
} |
156
|
|
|
|
|
|
|
|
157
|
10
|
100
|
|
|
|
27
|
if (($tabn - $TABLEN) == -1) { |
158
|
1
|
|
|
|
|
4
|
$output =~ s/,$/;/s; |
159
|
|
|
|
|
|
|
} |
160
|
|
|
|
|
|
|
|
161
|
10
|
|
|
|
|
35
|
return $output; |
162
|
|
|
|
|
|
|
} |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
sub dump_hash { |
165
|
2
|
|
|
2
|
0
|
5
|
my $var = shift; |
166
|
2
|
|
|
|
|
24
|
my $tabn = shift; |
167
|
2
|
|
|
|
|
5
|
my $output = shift; |
168
|
|
|
|
|
|
|
|
169
|
2
|
|
|
|
|
5
|
my $tab = " " x $tabn; |
170
|
|
|
|
|
|
|
#$output .= "$tab\n"; |
171
|
2
|
|
|
|
|
4
|
$tab .= " "; |
172
|
|
|
|
|
|
|
|
173
|
2
|
|
|
|
|
13
|
for my $elem (sort keys %$var) { |
174
|
6
|
50
|
|
|
|
13
|
if (ref $elem) { |
175
|
0
|
|
|
|
|
0
|
$output .= "$tab$elem => {" |
176
|
|
|
|
|
|
|
} else { |
177
|
6
|
|
|
|
|
14
|
$output .= "$tab'$elem' => "; |
178
|
|
|
|
|
|
|
} |
179
|
6
|
|
|
|
|
17
|
$output .= dumpvalue($var->{$elem},$tabn); |
180
|
|
|
|
|
|
|
} |
181
|
2
|
|
|
|
|
7
|
$output =~ s/\,$//s; # To remove the last ',' from the list |
182
|
|
|
|
|
|
|
|
183
|
2
|
|
|
|
|
8
|
return $output; |
184
|
|
|
|
|
|
|
} |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
sub dump_scalar { |
187
|
7
|
|
|
7
|
0
|
10
|
my $scalar = shift; |
188
|
7
|
|
|
|
|
9
|
my $tabn = shift; |
189
|
7
|
|
|
|
|
18
|
my $output = shift; |
190
|
|
|
|
|
|
|
|
191
|
7
|
100
|
|
|
|
27
|
if ($scalar !~ /\d+/) { $scalar = "'$scalar'" } |
|
5
|
|
|
|
|
10
|
|
192
|
|
|
|
|
|
|
|
193
|
7
|
|
|
|
|
11
|
$output .= "$scalar,\n"; |
194
|
|
|
|
|
|
|
|
195
|
7
|
|
|
|
|
17
|
return $output; |
196
|
|
|
|
|
|
|
} |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
sub dump_array { |
199
|
1
|
|
|
1
|
0
|
2
|
my $var = shift; |
200
|
1
|
|
|
|
|
3
|
my $tabn = shift; |
201
|
1
|
|
|
|
|
2
|
my $output = shift; |
202
|
|
|
|
|
|
|
|
203
|
1
|
|
|
|
|
1
|
my $i; |
204
|
|
|
|
|
|
|
|
205
|
1
|
|
|
|
|
4
|
my $tab = " " x $tabn; |
206
|
|
|
|
|
|
|
#$output .= "$tab\n"; |
207
|
|
|
|
|
|
|
#$output .= "$tab"; |
208
|
1
|
|
|
|
|
2
|
$tab .= " "; |
209
|
|
|
|
|
|
|
|
210
|
1
|
|
|
|
|
2
|
for my $elem (@$var) { |
211
|
3
|
|
|
|
|
6
|
$output .= $tab; |
212
|
|
|
|
|
|
|
#$output .= $i++; |
213
|
|
|
|
|
|
|
#$output .= " => "; |
214
|
3
|
|
|
|
|
9
|
$output .= dumpvalue($elem,$tabn); |
215
|
|
|
|
|
|
|
} |
216
|
1
|
|
|
|
|
5
|
$output =~ s/\,$//s; # To remove the last ',' from the list |
217
|
|
|
|
|
|
|
|
218
|
1
|
|
|
|
|
5
|
return $output; |
219
|
|
|
|
|
|
|
} |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
sub add_when { |
222
|
1
|
|
|
1
|
0
|
2
|
my $orig = shift; |
223
|
1
|
|
|
|
|
2
|
my $var = shift; |
224
|
1
|
|
|
|
|
2
|
my $op = shift; |
225
|
1
|
|
|
|
|
2
|
my $value = shift; |
226
|
|
|
|
|
|
|
|
227
|
1
|
|
|
|
|
1
|
push @{$Wait_Cond{$var}},[$op,$value]; |
|
1
|
|
|
|
|
5
|
|
228
|
1
|
|
|
|
|
3
|
return "$orig"; |
229
|
|
|
|
|
|
|
} |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
sub add_watch { |
232
|
7
|
|
|
7
|
0
|
20
|
my $orig = shift; |
233
|
7
|
|
|
|
|
16
|
my $var = my $var2 = shift; |
234
|
|
|
|
|
|
|
|
235
|
7
|
|
|
|
|
24
|
$var2 =~ s/[\$\@\%]//; |
236
|
|
|
|
|
|
|
|
237
|
7
|
|
|
|
|
10
|
my ($pre,$post,$init); |
238
|
|
|
|
|
|
|
|
239
|
7
|
50
|
|
|
|
49
|
if ($orig =~ /\s*my\s*[\@\$\%]/) { |
240
|
7
|
|
|
|
|
8
|
$pre = $orig; |
241
|
7
|
|
|
|
|
227
|
$pre =~ s/(\s*my\s*[\@\$\%]$var2).*/$1;/i; |
242
|
|
|
|
|
|
|
} |
243
|
|
|
|
|
|
|
|
244
|
7
|
100
|
|
|
|
42
|
if ($orig =~ /(=|\+\+|--)/) { |
245
|
3
|
|
|
|
|
7
|
$post = $orig; |
246
|
3
|
|
|
|
|
56
|
$post =~ s/.*([\@\$\%]$var2)/$1/si; |
247
|
|
|
|
|
|
|
} |
248
|
|
|
|
|
|
|
|
249
|
7
|
0
|
33
|
|
|
22
|
$init = ",\\$var" if (!$pre && !$post) ; |
250
|
|
|
|
|
|
|
|
251
|
7
|
|
|
|
|
59
|
return "$pre tie $var,'Devel::StealthDebug','$var'$init;$post"; |
252
|
|
|
|
|
|
|
} |
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
sub check_when_cond { |
255
|
15
|
|
|
15
|
0
|
16
|
my $object = shift; |
256
|
15
|
|
|
|
|
17
|
my $value = shift; |
257
|
15
|
|
|
|
|
20
|
my $index = shift; |
258
|
|
|
|
|
|
|
|
259
|
15
|
|
|
|
|
15
|
my $ok; |
260
|
15
|
|
|
|
|
15
|
for my $cond (@{$Wait_Cond{$object->{name}}}) { |
|
15
|
|
|
|
|
49
|
|
261
|
|
|
|
|
|
|
{ |
262
|
3
|
|
|
|
|
4
|
local ($@, $!); |
|
3
|
|
|
|
|
11
|
|
263
|
3
|
|
|
|
|
199
|
$ok = eval "\$object->{value} $$cond[0] $$cond[1]"; |
264
|
|
|
|
|
|
|
} |
265
|
|
|
|
|
|
|
|
266
|
3
|
100
|
|
|
|
16
|
if ($ok) { |
267
|
1
|
|
|
|
|
6
|
emit "$object->{name}$$cond[0]$$cond[1] !"; |
268
|
|
|
|
|
|
|
} |
269
|
|
|
|
|
|
|
} |
270
|
|
|
|
|
|
|
} |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
FILTER { |
273
|
|
|
|
|
|
|
# |
274
|
|
|
|
|
|
|
# Make it consistent and CLEAN ! |
275
|
|
|
|
|
|
|
# (Of course if it could work...) |
276
|
|
|
|
|
|
|
# |
277
|
|
|
|
|
|
|
# Should we really forbid pure comment lines |
278
|
|
|
|
|
|
|
# |
279
|
|
|
|
|
|
|
if ($ENABLE) { |
280
|
|
|
|
|
|
|
s/^([^#]*?)(#.*?!assert\((.+?)\)!)/add_assert($1,$3)/meg; |
281
|
|
|
|
|
|
|
s/^([^#]*?)(#.*?!watch\((.+?)\)!)/add_watch($1,$3)/meg; |
282
|
|
|
|
|
|
|
s/^([^#]*?)(#.*?!emit\((.+?)\)!)/add_emit($1,$3)/meg; |
283
|
|
|
|
|
|
|
s/^([^#]*?)(#.*?!dump\((.+?)\)!)/add_dump($1,$3)/meg; |
284
|
|
|
|
|
|
|
s/^([^#]*?)(#.*?!when\((.+?),(.+?),(.+?)\)!)/add_when($1,$3,$4,$5)/meg; |
285
|
|
|
|
|
|
|
s/^([^#]*?)(#.*?!emit_type\((.+?)\)!)/emit_type($1,$3)/meg; |
286
|
|
|
|
|
|
|
} |
287
|
|
|
|
|
|
|
if ($SOURCE) { print SOURCE "$_\n" } ; |
288
|
|
|
|
|
|
|
#s/(.)/$1/mg; |
289
|
|
|
|
|
|
|
}; |
290
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
sub TIESCALAR { |
292
|
3
|
|
|
3
|
|
35
|
my $class = shift; |
293
|
3
|
|
|
|
|
6
|
my $name = shift; |
294
|
3
|
|
|
|
|
6
|
my $value = shift; |
295
|
3
|
|
|
|
|
6
|
my %object; |
296
|
|
|
|
|
|
|
|
297
|
3
|
|
|
|
|
6
|
$object{name}=$name; |
298
|
3
|
50
|
|
|
|
11
|
$object{value}=$$value if ($value) ; |
299
|
3
|
|
|
|
|
14
|
bless \%object,$class; |
300
|
|
|
|
|
|
|
} |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
sub FETCH { |
303
|
15
|
|
|
15
|
|
74
|
my $object = shift; |
304
|
15
|
|
|
|
|
20
|
my $index = shift; |
305
|
|
|
|
|
|
|
|
306
|
15
|
100
|
|
|
|
81
|
if ($object->{name} =~ /^\@/) { |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
307
|
4
|
|
|
|
|
382
|
carp "FETCH ($object->{name}\[$index\] -> ",$object->{value}[$index],")"; |
308
|
4
|
|
|
|
|
164
|
return $object->{value}[$index]; |
309
|
|
|
|
|
|
|
} elsif ($object->{name} =~ /^\$/) { |
310
|
7
|
|
|
|
|
728
|
carp "FETCH ($object->{name} -> ",$object->{value},")"; |
311
|
7
|
|
|
|
|
240
|
return $object->{value}; |
312
|
|
|
|
|
|
|
} elsif ($object->{name} =~ /^\%/) { |
313
|
4
|
|
|
|
|
396
|
carp "FETCH ($object->{name}\{$index\} -> ",$object->{value}{$index},")"; |
314
|
4
|
|
|
|
|
167
|
return $object->{value}{$index}; |
315
|
|
|
|
|
|
|
} else { |
316
|
0
|
|
|
|
|
0
|
carp "Strange FETCH" |
317
|
|
|
|
|
|
|
} |
318
|
|
|
|
|
|
|
} |
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
sub FETCHSIZE { |
321
|
0
|
|
|
0
|
|
0
|
my $object = shift; |
322
|
0
|
|
|
|
|
0
|
my $value = shift; |
323
|
|
|
|
|
|
|
|
324
|
0
|
|
|
|
|
0
|
$#{$object->{value}}=$value; |
|
0
|
|
|
|
|
0
|
|
325
|
0
|
|
|
|
|
0
|
carp "FETCHSIZE ($object->{name})($value)"; |
326
|
|
|
|
|
|
|
} |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
sub STORE { |
329
|
15
|
|
|
15
|
|
56
|
my $object = shift; |
330
|
15
|
|
|
|
|
23
|
my $value = pop; |
331
|
15
|
|
|
|
|
21
|
my $index = shift; |
332
|
|
|
|
|
|
|
|
333
|
15
|
100
|
|
|
|
99
|
if ($object->{name} =~ /^\@/) { |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
334
|
4
|
|
|
|
|
9
|
$object->{value}[$index]=$value; |
335
|
4
|
|
|
|
|
8
|
check_when_cond($object,$value,$index); |
336
|
4
|
|
|
|
|
369
|
carp "STORE ($object->{name}\[$index\] <- $object->{value}[$index])"; |
337
|
4
|
|
|
|
|
164
|
return $object->{value}[$index]; |
338
|
|
|
|
|
|
|
} elsif ($object->{name} =~ /^\$/) { |
339
|
7
|
|
|
|
|
13
|
$object->{value}=$value; |
340
|
7
|
|
|
|
|
18
|
check_when_cond($object,$value,$index); |
341
|
6
|
|
|
|
|
735
|
carp "STORE ($object->{name} <- $object->{value})"; |
342
|
6
|
|
|
|
|
228
|
return $object->{value}; |
343
|
|
|
|
|
|
|
} elsif ($object->{name} =~ /^\%/) { |
344
|
4
|
|
|
|
|
11
|
$object->{value}{$index}=$value; |
345
|
4
|
|
|
|
|
12
|
check_when_cond($object,$value,$index); |
346
|
4
|
|
|
|
|
579
|
carp "STORE ($object->{name}\{$index\} <- $object->{value}{$index})"; |
347
|
4
|
|
|
|
|
294
|
return $object->{value}{$index}; |
348
|
|
|
|
|
|
|
} |
349
|
|
|
|
|
|
|
} |
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
sub CLEAR { |
352
|
0
|
|
|
0
|
|
0
|
my $object = shift; |
353
|
|
|
|
|
|
|
|
354
|
0
|
|
|
|
|
0
|
$object->{value}=[]; |
355
|
0
|
|
|
|
|
0
|
carp "CLEAR ($object->{name})"; |
356
|
|
|
|
|
|
|
} |
357
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
sub TIEARRAY { |
359
|
2
|
|
|
2
|
|
17
|
my $class = shift; |
360
|
2
|
|
|
|
|
4
|
my $name = shift; |
361
|
2
|
|
|
|
|
3
|
my $value = shift; |
362
|
2
|
|
|
|
|
4
|
my %object; |
363
|
|
|
|
|
|
|
|
364
|
2
|
|
|
|
|
44
|
$object{name} = $name; |
365
|
2
|
50
|
|
|
|
9
|
$object{value}= $value?$value:[]; |
366
|
2
|
|
|
|
|
9
|
bless \%object,$class; |
367
|
|
|
|
|
|
|
} |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
sub TIEHASH { |
370
|
2
|
|
|
2
|
|
1367
|
my $class = shift; |
371
|
2
|
|
|
|
|
5
|
my $name = shift; |
372
|
2
|
|
|
|
|
4
|
my $value = shift; |
373
|
2
|
|
|
|
|
4
|
my %object; |
374
|
|
|
|
|
|
|
|
375
|
2
|
|
|
|
|
5
|
$object{name} = $name; |
376
|
2
|
50
|
|
|
|
11
|
$object{value}= $value?$value:{}; |
377
|
2
|
|
|
|
|
10
|
bless \%object,$class; |
378
|
|
|
|
|
|
|
} |
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
sub DELETE { |
381
|
0
|
|
|
0
|
|
0
|
my $object = shift; |
382
|
0
|
|
|
|
|
0
|
my $key = shift; |
383
|
|
|
|
|
|
|
|
384
|
0
|
|
|
|
|
0
|
delete $object->{value}{$key}; |
385
|
0
|
|
|
|
|
0
|
carp "DELETE ($object->{name})($key)"; |
386
|
|
|
|
|
|
|
} |
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
sub EXISTS { |
389
|
0
|
|
|
0
|
|
0
|
my $object = shift; |
390
|
0
|
|
|
|
|
0
|
my $key = shift;; |
391
|
|
|
|
|
|
|
|
392
|
0
|
|
|
|
|
0
|
carp "EXISTS ($object->{name})($key)"; |
393
|
|
|
|
|
|
|
|
394
|
0
|
0
|
|
|
|
0
|
return 0 if $object->{value}{$key}; |
395
|
0
|
|
|
|
|
0
|
return 1; |
396
|
|
|
|
|
|
|
} |
397
|
|
|
|
|
|
|
|
398
|
|
|
|
|
|
|
sub FIRSTKEY { |
399
|
0
|
|
|
0
|
|
0
|
my $object = shift; |
400
|
0
|
|
|
|
|
0
|
my $toreseteach = keys %{$object->{value}}; |
|
0
|
|
|
|
|
0
|
|
401
|
|
|
|
|
|
|
|
402
|
0
|
|
|
|
|
0
|
$object->{lastkey} = each %{$object->{value}}; |
|
0
|
|
|
|
|
0
|
|
403
|
0
|
|
|
|
|
0
|
carp "FIRSTKEY ($object->{name})(",$object->{lastkey},")"; |
404
|
0
|
|
|
|
|
0
|
return $object->{lastkey} |
405
|
|
|
|
|
|
|
} |
406
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
sub NEXTKEY { |
408
|
0
|
|
|
0
|
|
0
|
my $object = shift; |
409
|
0
|
|
|
|
|
0
|
my $key = shift; |
410
|
0
|
|
|
|
|
0
|
my $lastkey = shift; |
411
|
|
|
|
|
|
|
|
412
|
0
|
|
|
|
|
0
|
carp "NEXTKEY ($object->{name})($key)($lastkey)"; |
413
|
0
|
|
|
|
|
0
|
return each %{$object->{value}} |
|
0
|
|
|
|
|
0
|
|
414
|
|
|
|
|
|
|
} |
415
|
|
|
|
|
|
|
|
416
|
|
|
|
|
|
|
sub DESTROY { |
417
|
7
|
|
|
7
|
|
15303
|
my $object = shift; |
418
|
|
|
|
|
|
|
|
419
|
7
|
|
|
|
|
5262
|
carp "DESTROY ($object->{name})"; |
420
|
|
|
|
|
|
|
} |
421
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
sub STORESIZE { |
424
|
0
|
|
|
0
|
|
|
my $object = shift; |
425
|
0
|
|
|
|
|
|
my $count = shift; |
426
|
|
|
|
|
|
|
|
427
|
0
|
|
|
|
|
|
carp "STORESIZE ($object)($count)"; |
428
|
|
|
|
|
|
|
} |
429
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
sub PUSH { |
431
|
0
|
|
|
0
|
|
|
my $object = shift; |
432
|
0
|
|
|
|
|
|
my @list = @_; |
433
|
|
|
|
|
|
|
|
434
|
0
|
|
|
|
|
|
push @{$object->{value}},@list; |
|
0
|
|
|
|
|
|
|
435
|
0
|
|
|
|
|
|
carp "PUSH ($object)(@list)"; |
436
|
|
|
|
|
|
|
} |
437
|
|
|
|
|
|
|
|
438
|
|
|
|
|
|
|
sub POP { |
439
|
0
|
|
|
0
|
|
|
my $object = shift; |
440
|
0
|
|
|
|
|
|
my $value = pop @{$object->{value}}; |
|
0
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
|
442
|
0
|
|
|
|
|
|
carp "POP ($object)($value)"; |
443
|
|
|
|
|
|
|
} |
444
|
|
|
|
|
|
|
|
445
|
|
|
|
|
|
|
sub SHIFT { |
446
|
0
|
|
|
0
|
|
|
my $object = shift; |
447
|
0
|
|
|
|
|
|
my $value = shift @{$object->{value}}; |
|
0
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
|
449
|
0
|
|
|
|
|
|
carp "SHIFT ($object)($value)"; |
450
|
|
|
|
|
|
|
} |
451
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
sub UNSHIFT { |
453
|
0
|
|
|
0
|
|
|
my $object = shift; |
454
|
0
|
|
|
|
|
|
my @list = @_; |
455
|
|
|
|
|
|
|
|
456
|
0
|
|
|
|
|
|
unshift @{$object->{value}},@list; |
|
0
|
|
|
|
|
|
|
457
|
0
|
|
|
|
|
|
carp "SHIFT ($object)(@list)"; |
458
|
|
|
|
|
|
|
} |
459
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
sub SPLICE { |
461
|
0
|
|
|
0
|
|
|
my $object = shift; |
462
|
0
|
|
|
|
|
|
my $offset = shift; |
463
|
0
|
|
|
|
|
|
my $length = shift; |
464
|
0
|
|
|
|
|
|
my @list = @_; |
465
|
|
|
|
|
|
|
|
466
|
0
|
|
|
|
|
|
return splice @{$object->{value}},$offset,$length,@list |
|
0
|
|
|
|
|
|
|
467
|
|
|
|
|
|
|
} |
468
|
|
|
|
|
|
|
|
469
|
|
|
|
|
|
|
sub EXTEND { |
470
|
0
|
|
|
0
|
|
|
my $object = shift; |
471
|
0
|
|
|
|
|
|
my $count = shift; |
472
|
|
|
|
|
|
|
|
473
|
|
|
|
|
|
|
# Nothing to do ? |
474
|
0
|
|
|
|
|
|
carp "EXTEND (",$object->STORESIZE,")"; |
475
|
|
|
|
|
|
|
} |
476
|
|
|
|
|
|
|
|
477
|
|
|
|
|
|
|
1; |
478
|
|
|
|
|
|
|
|
479
|
|
|
|
|
|
|
__END__ |