| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
# vi: set autoindent shiftwidth=4 tabstop=8 softtabstop=4 expandtab: |
|
2
|
|
|
|
|
|
|
package DB; |
|
3
|
|
|
|
|
|
|
|
|
4
|
1
|
|
|
1
|
|
21695
|
use 5.006001; |
|
|
1
|
|
|
|
|
3
|
|
|
5
|
1
|
|
|
1
|
|
5
|
use strict; |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
28
|
|
|
6
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
|
1
|
|
|
|
|
5
|
|
|
|
1
|
|
|
|
|
33
|
|
|
7
|
|
|
|
|
|
|
|
|
8
|
1
|
|
|
1
|
|
5
|
use Carp; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
85
|
|
|
9
|
1
|
|
|
1
|
|
8
|
use B qw(svref_2object comppadlist class); |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
66
|
|
|
10
|
1
|
|
|
1
|
|
17221
|
use B::Showlex; |
|
|
1
|
|
|
|
|
21166
|
|
|
|
1
|
|
|
|
|
31
|
|
|
11
|
1
|
|
|
1
|
|
451
|
use Curses; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
use Curses::UI; |
|
13
|
|
|
|
|
|
|
use Curses::UI::Common; |
|
14
|
|
|
|
|
|
|
use Data::Dumper; |
|
15
|
|
|
|
|
|
|
use Cwd; |
|
16
|
|
|
|
|
|
|
use File::Basename; |
|
17
|
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
use Devel::PDB::Source; |
|
19
|
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
use vars qw(*dbline $usercontext $db_stop $ini_warn); |
|
21
|
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
our $VERSION = '1.6'; |
|
23
|
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
our $single; |
|
25
|
|
|
|
|
|
|
our $sub; |
|
26
|
|
|
|
|
|
|
our $trace; |
|
27
|
|
|
|
|
|
|
our $signal; |
|
28
|
|
|
|
|
|
|
our $stack_depth; |
|
29
|
|
|
|
|
|
|
our @stack; |
|
30
|
|
|
|
|
|
|
our $current_sub; |
|
31
|
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
my @compiled; |
|
33
|
|
|
|
|
|
|
my $inited = 0; |
|
34
|
|
|
|
|
|
|
my $cui; |
|
35
|
|
|
|
|
|
|
my $sv_win; |
|
36
|
|
|
|
|
|
|
my $sv; |
|
37
|
|
|
|
|
|
|
my $exit = 0; |
|
38
|
|
|
|
|
|
|
my $db_exit = 0; |
|
39
|
|
|
|
|
|
|
my $yield; |
|
40
|
|
|
|
|
|
|
my %sources; |
|
41
|
|
|
|
|
|
|
my $new_single; |
|
42
|
|
|
|
|
|
|
my $current_source; |
|
43
|
|
|
|
|
|
|
my $evalarg; |
|
44
|
|
|
|
|
|
|
my $package; |
|
45
|
|
|
|
|
|
|
my $filename; |
|
46
|
|
|
|
|
|
|
my $line; |
|
47
|
|
|
|
|
|
|
my @watch_exprs; |
|
48
|
|
|
|
|
|
|
my $update_watch_list; |
|
49
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
my $std_file_win; |
|
51
|
|
|
|
|
|
|
my $std_file; |
|
52
|
|
|
|
|
|
|
my $help_win; |
|
53
|
|
|
|
|
|
|
my $help; |
|
54
|
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
my $lower_win; |
|
56
|
|
|
|
|
|
|
my $auto_win; |
|
57
|
|
|
|
|
|
|
my $watch_win; |
|
58
|
|
|
|
|
|
|
my $padvar_list; |
|
59
|
|
|
|
|
|
|
my $watch_list; |
|
60
|
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
my $padlist_scope; |
|
62
|
|
|
|
|
|
|
my %padlist; |
|
63
|
|
|
|
|
|
|
my @padlist_disp; |
|
64
|
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
my $stdout; |
|
66
|
|
|
|
|
|
|
my $stderr; |
|
67
|
|
|
|
|
|
|
my $output; |
|
68
|
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
my $user_conf_readed = 0; |
|
70
|
|
|
|
|
|
|
my $ui_window_focused = 0; |
|
71
|
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
$trace = $signal = $single = 0; |
|
73
|
|
|
|
|
|
|
$stack_depth = 0; |
|
74
|
|
|
|
|
|
|
@stack = (0); |
|
75
|
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
my %def_style = ( |
|
77
|
|
|
|
|
|
|
-bg => 'white', |
|
78
|
|
|
|
|
|
|
-fg => 'blue', |
|
79
|
|
|
|
|
|
|
-bbg => 'blue', |
|
80
|
|
|
|
|
|
|
-bfg => 'white', |
|
81
|
|
|
|
|
|
|
-tbg => 'white', |
|
82
|
|
|
|
|
|
|
-tfg => 'blue', |
|
83
|
|
|
|
|
|
|
); |
|
84
|
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
# |
|
86
|
|
|
|
|
|
|
# Set or return window colour style |
|
87
|
|
|
|
|
|
|
# |
|
88
|
|
|
|
|
|
|
sub window_style { |
|
89
|
|
|
|
|
|
|
if (@_) { |
|
90
|
|
|
|
|
|
|
my %h = @_; |
|
91
|
|
|
|
|
|
|
while (my ($k, $v) = each %h) { |
|
92
|
|
|
|
|
|
|
$def_style{$k} = $v if ($k =~ /^-[tbs]?[fb]g$/); |
|
93
|
|
|
|
|
|
|
} |
|
94
|
|
|
|
|
|
|
} |
|
95
|
|
|
|
|
|
|
return %def_style; |
|
96
|
|
|
|
|
|
|
} |
|
97
|
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
BEGIN { |
|
99
|
|
|
|
|
|
|
$Devel::PDB::scriptName = $0; |
|
100
|
|
|
|
|
|
|
@Devel::PDB::script_args = @ARGV; # copy args |
|
101
|
|
|
|
|
|
|
$ini_warn = $^W; |
|
102
|
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
# This is the flag that says "a debugger is running, please call |
|
104
|
|
|
|
|
|
|
# DB::DB and DB::sub". We will turn it on forcibly before we try to |
|
105
|
|
|
|
|
|
|
# execute anything in the user's context, because we always want to |
|
106
|
|
|
|
|
|
|
# get control back. |
|
107
|
|
|
|
|
|
|
$db_stop = 0; # Compiler warning ... |
|
108
|
|
|
|
|
|
|
$db_stop = 1 << 30; # ... because this is only used in an eval() later. |
|
109
|
|
|
|
|
|
|
} |
|
110
|
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
END { |
|
112
|
|
|
|
|
|
|
open STDOUT, ">>&", $stdout if $stdout; |
|
113
|
|
|
|
|
|
|
$single = 0; |
|
114
|
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
# Save actual breakpoints and watches |
|
116
|
|
|
|
|
|
|
save_state_file(config_file("conf.rc")); |
|
117
|
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
my @ab = ({ |
|
119
|
|
|
|
|
|
|
-label => '< Quit >', |
|
120
|
|
|
|
|
|
|
-value => 1, |
|
121
|
|
|
|
|
|
|
-shortcut => 'q' |
|
122
|
|
|
|
|
|
|
}, |
|
123
|
|
|
|
|
|
|
{ -label => '< Show STD* files >', |
|
124
|
|
|
|
|
|
|
-value => 2, |
|
125
|
|
|
|
|
|
|
-shortcut => 'f' |
|
126
|
|
|
|
|
|
|
}, |
|
127
|
|
|
|
|
|
|
{ -label => '< Restart >', |
|
128
|
|
|
|
|
|
|
-value => 3, |
|
129
|
|
|
|
|
|
|
-shortcut => 'r' |
|
130
|
|
|
|
|
|
|
}, |
|
131
|
|
|
|
|
|
|
{ -label => '< Save config & Quit >', |
|
132
|
|
|
|
|
|
|
-value => 4, |
|
133
|
|
|
|
|
|
|
-shortcut => 's' |
|
134
|
|
|
|
|
|
|
}, |
|
135
|
|
|
|
|
|
|
{ -label => '< Save config & Restart >', |
|
136
|
|
|
|
|
|
|
-value => 'a', |
|
137
|
|
|
|
|
|
|
-shortcut => 5 |
|
138
|
|
|
|
|
|
|
}, |
|
139
|
|
|
|
|
|
|
); |
|
140
|
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
my $exitloop = ($db_exit || !$cui) ? 1 : 0; |
|
142
|
|
|
|
|
|
|
while (!$exitloop) { |
|
143
|
|
|
|
|
|
|
my $t = $cui->dialog( |
|
144
|
|
|
|
|
|
|
-title => 'Exiting', |
|
145
|
|
|
|
|
|
|
-buttons => \@ab, |
|
146
|
|
|
|
|
|
|
-message => 'Choose one of this functions : ', |
|
147
|
|
|
|
|
|
|
window_style(), |
|
148
|
|
|
|
|
|
|
); |
|
149
|
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
if ($t == 1) { |
|
151
|
|
|
|
|
|
|
$exitloop = 1; |
|
152
|
|
|
|
|
|
|
} elsif ($t == 2) { |
|
153
|
|
|
|
|
|
|
db_view_std_files(1); |
|
154
|
|
|
|
|
|
|
} elsif ($t == 3) { |
|
155
|
|
|
|
|
|
|
DoRestart(); |
|
156
|
|
|
|
|
|
|
} elsif ($t == 4) { |
|
157
|
|
|
|
|
|
|
save_state_file(config_file("conf")); |
|
158
|
|
|
|
|
|
|
$exitloop = 1; |
|
159
|
|
|
|
|
|
|
} elsif ($t == 5) { |
|
160
|
|
|
|
|
|
|
save_state_file(config_file("conf")); |
|
161
|
|
|
|
|
|
|
DoRestart(); |
|
162
|
|
|
|
|
|
|
} |
|
163
|
|
|
|
|
|
|
} |
|
164
|
|
|
|
|
|
|
endwin(); |
|
165
|
|
|
|
|
|
|
} |
|
166
|
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
# |
|
168
|
|
|
|
|
|
|
# Method for restarting debugger |
|
169
|
|
|
|
|
|
|
# |
|
170
|
|
|
|
|
|
|
sub DoRestart { |
|
171
|
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
# There is problem with Destroyer in Curses::UI |
|
173
|
|
|
|
|
|
|
endwin(); |
|
174
|
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
# We must destroyed $cui |
|
176
|
|
|
|
|
|
|
$cui = undef; |
|
177
|
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
my @flags = (); |
|
179
|
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
# If warn was on before, turn it on again. |
|
181
|
|
|
|
|
|
|
push @flags, '-w' if $ini_warn; |
|
182
|
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
# Rebuild the -I flags that were on the initial # command line. |
|
184
|
|
|
|
|
|
|
my %h_inc = @INC; |
|
185
|
|
|
|
|
|
|
foreach (split(" ", `perl -e 'print "\@INC";'`)) { |
|
186
|
|
|
|
|
|
|
delete($h_inc{$_}); |
|
187
|
|
|
|
|
|
|
} |
|
188
|
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
foreach (keys %h_inc) { |
|
190
|
|
|
|
|
|
|
push @flags, '-I', $_; |
|
191
|
|
|
|
|
|
|
} |
|
192
|
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
# Turn on taint if it was on before. |
|
194
|
|
|
|
|
|
|
push @flags, '-T' if ${^TAINT}; |
|
195
|
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
if ($Devel::PDB::scriptName eq '-e') { |
|
197
|
|
|
|
|
|
|
my $cl; |
|
198
|
|
|
|
|
|
|
my $lines = *{$main::{'_<-e'}}{ARRAY}; |
|
199
|
|
|
|
|
|
|
for (1 .. $#$lines) { # The first line is PERL5DB |
|
200
|
|
|
|
|
|
|
chomp($cl = $lines->[$_]); |
|
201
|
|
|
|
|
|
|
push @flags, '-e', $cl; |
|
202
|
|
|
|
|
|
|
} |
|
203
|
|
|
|
|
|
|
} elsif ($Devel::PDB::scriptName !~ /perl/) { |
|
204
|
|
|
|
|
|
|
push @flags, $Devel::PDB::scriptName; |
|
205
|
|
|
|
|
|
|
} |
|
206
|
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
# print "$$ doing a restart with $fname\n" ; |
|
208
|
|
|
|
|
|
|
exec "perl", "-d:PDB", @flags, @Devel::PDB::script_args; |
|
209
|
|
|
|
|
|
|
} |
|
210
|
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
# |
|
212
|
|
|
|
|
|
|
# print any error which is put as arguments |
|
213
|
|
|
|
|
|
|
# |
|
214
|
|
|
|
|
|
|
sub print_error { |
|
215
|
|
|
|
|
|
|
$cui->error( |
|
216
|
|
|
|
|
|
|
-title => "Error", |
|
217
|
|
|
|
|
|
|
-message => join("\n", @_), |
|
218
|
|
|
|
|
|
|
DB::window_style(), |
|
219
|
|
|
|
|
|
|
) if ($cui); |
|
220
|
|
|
|
|
|
|
} |
|
221
|
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
# |
|
223
|
|
|
|
|
|
|
# returns true if line is breakable |
|
224
|
|
|
|
|
|
|
# |
|
225
|
|
|
|
|
|
|
sub checkdbline($$) { |
|
226
|
|
|
|
|
|
|
my ($fname, $lineno) = @_; |
|
227
|
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
return 0 unless $fname; # we're getting an undef here on 'Restart...' |
|
229
|
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
local ($^W) = 0; # spares us warnings under -w |
|
231
|
|
|
|
|
|
|
local (*dbline) = $main::{'_<' . $fname}; |
|
232
|
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
my $flag = $dbline[$lineno] != 0; |
|
234
|
|
|
|
|
|
|
return $flag; |
|
235
|
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
} # end of checkdbline |
|
237
|
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
# |
|
239
|
|
|
|
|
|
|
# sets a breakpoint 'through' a magic |
|
240
|
|
|
|
|
|
|
# variable that perl is able to interpert |
|
241
|
|
|
|
|
|
|
# |
|
242
|
|
|
|
|
|
|
sub setdbline($$$) { |
|
243
|
|
|
|
|
|
|
my ($fname, $lineno, $value) = @_; |
|
244
|
|
|
|
|
|
|
local (*dbline) = $main::{'_<' . $fname}; |
|
245
|
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
$dbline{$lineno} = $value; |
|
247
|
|
|
|
|
|
|
} # end of setdbline |
|
248
|
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
sub getdbline($$) { |
|
250
|
|
|
|
|
|
|
my ($fname, $lineno) = @_; |
|
251
|
|
|
|
|
|
|
local (*dbline) = $main::{'_<' . $fname}; |
|
252
|
|
|
|
|
|
|
return $dbline{$lineno}; |
|
253
|
|
|
|
|
|
|
} # end of getdbline |
|
254
|
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
sub getdbtextline { |
|
256
|
|
|
|
|
|
|
my ($fname, $lineno) = @_; |
|
257
|
|
|
|
|
|
|
local (*dbline) = $main::{'_<' . $fname}; |
|
258
|
|
|
|
|
|
|
return $dbline[$lineno]; |
|
259
|
|
|
|
|
|
|
} # end of getdbline |
|
260
|
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
sub cleardbline($$;&) { |
|
262
|
|
|
|
|
|
|
my ($fname, $lineno, $clearsub) = @_; |
|
263
|
|
|
|
|
|
|
local (*dbline) = $main::{'_<' . $fname}; |
|
264
|
|
|
|
|
|
|
my $value; # just in case we want it for something |
|
265
|
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
$value = $dbline{$lineno}; |
|
267
|
|
|
|
|
|
|
delete $dbline{$lineno}; |
|
268
|
|
|
|
|
|
|
&$clearsub($value) if $value && $clearsub; |
|
269
|
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
return $value; |
|
271
|
|
|
|
|
|
|
} # end of cleardbline |
|
272
|
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
sub clearalldblines(;&) { |
|
274
|
|
|
|
|
|
|
my ($clearsub) = @_; |
|
275
|
|
|
|
|
|
|
my ($key, $value, $brkPt, $dbkey); |
|
276
|
|
|
|
|
|
|
local (*dbline); |
|
277
|
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
while (($key, $value) = each %main::) { # key loop |
|
279
|
|
|
|
|
|
|
next unless $key =~ /^_; |
|
280
|
|
|
|
|
|
|
*dbline = $value; |
|
281
|
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
foreach $dbkey (keys %dbline) { |
|
283
|
|
|
|
|
|
|
$brkPt = $dbline{$dbkey}; |
|
284
|
|
|
|
|
|
|
delete $dbline{$dbkey}; |
|
285
|
|
|
|
|
|
|
next unless $brkPt && $clearsub; |
|
286
|
|
|
|
|
|
|
&$clearsub($brkPt); # if specificed, call the sub routine to clear the breakpoint |
|
287
|
|
|
|
|
|
|
} |
|
288
|
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
} # end of key loop |
|
290
|
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
} # end of clearalldblines |
|
292
|
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
sub getdblineindexes { |
|
294
|
|
|
|
|
|
|
my ($fname) = @_; |
|
295
|
|
|
|
|
|
|
local (*dbline) = $main::{'_<' . $fname}; |
|
296
|
|
|
|
|
|
|
return keys %dbline; |
|
297
|
|
|
|
|
|
|
} # end of getdblineindexes |
|
298
|
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
# |
|
300
|
|
|
|
|
|
|
# Return list of breakpoints from files which are add as arguments |
|
301
|
|
|
|
|
|
|
# |
|
302
|
|
|
|
|
|
|
sub getbreakpoints { |
|
303
|
|
|
|
|
|
|
my (@fnames) = @_; |
|
304
|
|
|
|
|
|
|
my ($fname, @retList); |
|
305
|
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
foreach $fname (@fnames) { |
|
307
|
|
|
|
|
|
|
next unless $main::{'_<' . $fname}; |
|
308
|
|
|
|
|
|
|
local (*dbline) = $main::{'_<' . $fname}; |
|
309
|
|
|
|
|
|
|
push @retList, values %dbline; |
|
310
|
|
|
|
|
|
|
} |
|
311
|
|
|
|
|
|
|
return @retList; |
|
312
|
|
|
|
|
|
|
} # end of getbreakpoints |
|
313
|
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
# |
|
315
|
|
|
|
|
|
|
# Return filename from param and remove _< character from begin |
|
316
|
|
|
|
|
|
|
# |
|
317
|
|
|
|
|
|
|
sub retfilename { |
|
318
|
|
|
|
|
|
|
my $f = shift; |
|
319
|
|
|
|
|
|
|
$f =~ s/^_/; |
|
320
|
|
|
|
|
|
|
return $f; |
|
321
|
|
|
|
|
|
|
} |
|
322
|
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
# |
|
324
|
|
|
|
|
|
|
# Construct a hash of the files |
|
325
|
|
|
|
|
|
|
# that have breakpoints to save |
|
326
|
|
|
|
|
|
|
# |
|
327
|
|
|
|
|
|
|
sub breakpoints_to_save { |
|
328
|
|
|
|
|
|
|
my %brkList = (); |
|
329
|
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
foreach my $file (keys %main::) { # file loop |
|
331
|
|
|
|
|
|
|
next unless $file =~ /^_ && exists $main::{$file}; |
|
332
|
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
#my @k = getdblineindexes(retfilename($file)); |
|
334
|
|
|
|
|
|
|
local (*dbline) = $main::{$file}; |
|
335
|
|
|
|
|
|
|
my @a = (); |
|
336
|
|
|
|
|
|
|
while (my ($k, $d) = each %dbline) { |
|
337
|
|
|
|
|
|
|
push(@a, {'line' => $k, 'breakpoint' => $d}) if ($d); |
|
338
|
|
|
|
|
|
|
} |
|
339
|
|
|
|
|
|
|
$brkList{$file} = \@a if (scalar(@a)); |
|
340
|
|
|
|
|
|
|
} # end of file loop |
|
341
|
|
|
|
|
|
|
return \%brkList; |
|
342
|
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
} # end of breakpoints_to_save |
|
344
|
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
# |
|
346
|
|
|
|
|
|
|
# When we restore breakpoints from a state file |
|
347
|
|
|
|
|
|
|
# they've often 'moved' because the file |
|
348
|
|
|
|
|
|
|
# has been editted. |
|
349
|
|
|
|
|
|
|
# |
|
350
|
|
|
|
|
|
|
# We search for the line starting with the original line number, |
|
351
|
|
|
|
|
|
|
# then we walk it back 20 lines, then with line right after the |
|
352
|
|
|
|
|
|
|
# orginal line number and walk forward 20 lines. |
|
353
|
|
|
|
|
|
|
# |
|
354
|
|
|
|
|
|
|
# NOTE: dbline is expected to be 'local' |
|
355
|
|
|
|
|
|
|
# when called |
|
356
|
|
|
|
|
|
|
# |
|
357
|
|
|
|
|
|
|
sub fix_breakpoints { |
|
358
|
|
|
|
|
|
|
my (@brkPts) = @_; |
|
359
|
|
|
|
|
|
|
my ($startLine, $endLine, $nLines, $brkPt); |
|
360
|
|
|
|
|
|
|
my (@retList); |
|
361
|
|
|
|
|
|
|
local ($^W) = 0; |
|
362
|
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
$nLines = scalar @dbline; |
|
364
|
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
foreach $brkPt (@brkPts) { |
|
366
|
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
#$startLine = $brkPt->{'line'} > 20 ? $brkPt->{'line'} - 20 : 0 ; |
|
368
|
|
|
|
|
|
|
#$endLine = $brkPt->{'line'} < $nLines - 20 ? $brkPt->{'line'} + 20 : $nLines ; |
|
369
|
|
|
|
|
|
|
# |
|
370
|
|
|
|
|
|
|
#for( (reverse $startLine..$brkPt->{'line'}), $brkPt->{'line'} + 1 .. $endLine ) { |
|
371
|
|
|
|
|
|
|
# next unless $brkPt->{'text'} eq $dbline[$_] ; |
|
372
|
|
|
|
|
|
|
# $brkPt->{'line'} = $_ ; |
|
373
|
|
|
|
|
|
|
# push @retList, $brkPt ; |
|
374
|
|
|
|
|
|
|
# last ; |
|
375
|
|
|
|
|
|
|
#} |
|
376
|
|
|
|
|
|
|
push @retList, $brkPt; |
|
377
|
|
|
|
|
|
|
} # end of breakpoint list |
|
378
|
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
return @retList; |
|
380
|
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
} # end of fix_breakpoints |
|
382
|
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
sub set_breakpoints { |
|
384
|
|
|
|
|
|
|
my ($fname, $newList) = @_; |
|
385
|
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
local (*dbline) = $main::{$fname}; |
|
387
|
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
my $offset = 0; |
|
389
|
|
|
|
|
|
|
$offset = 1 if $dbline[1] =~ /use\s+.*Devel::_?PDB/; |
|
390
|
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
foreach my $brkPt (@$newList) { |
|
392
|
|
|
|
|
|
|
if (!checkdbline(retfilename($fname), $brkPt->{'line'} + $offset)) { |
|
393
|
|
|
|
|
|
|
print_error("Breakpoint $fname:$brkPt->{'line'} in config file is not breakable."); |
|
394
|
|
|
|
|
|
|
next; |
|
395
|
|
|
|
|
|
|
} |
|
396
|
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
#$dbline{$brkPt->{'line'}} = { %$brkPt } ; # make a fresh copy |
|
398
|
|
|
|
|
|
|
$dbline{$brkPt->{'line'}} = exists($brkPt->{'breakpoint'}) ? $brkPt->{'breakpoint'} : 1; |
|
399
|
|
|
|
|
|
|
} |
|
400
|
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
} |
|
402
|
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
my %postponed_file = (); |
|
404
|
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
# |
|
406
|
|
|
|
|
|
|
# Restore breakpoints saved above |
|
407
|
|
|
|
|
|
|
# |
|
408
|
|
|
|
|
|
|
sub restore_breakpoints_from_save { |
|
409
|
|
|
|
|
|
|
my ($brkList) = @_; |
|
410
|
|
|
|
|
|
|
my ($key, $list, @newList); |
|
411
|
|
|
|
|
|
|
|
|
412
|
|
|
|
|
|
|
while (($key, $list) = each %$brkList) { # reinsert loop |
|
413
|
|
|
|
|
|
|
$postponed_file{$key} = $list; |
|
414
|
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
next unless exists $main::{$key}; |
|
416
|
|
|
|
|
|
|
|
|
417
|
|
|
|
|
|
|
@newList = fix_breakpoints(@$list); |
|
418
|
|
|
|
|
|
|
set_breakpoints($key, \@newList); |
|
419
|
|
|
|
|
|
|
} # end of reinsert loop |
|
420
|
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
} # end of restore_breakpoints_from_save ; |
|
422
|
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
# |
|
424
|
|
|
|
|
|
|
# Loading watches and breakpoint from state file(it is param) |
|
425
|
|
|
|
|
|
|
# |
|
426
|
|
|
|
|
|
|
sub load_state_file { |
|
427
|
|
|
|
|
|
|
my ($fName) = @_; |
|
428
|
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
if (-e $fName && -r $fName) { |
|
430
|
|
|
|
|
|
|
no strict; |
|
431
|
|
|
|
|
|
|
local ($files, $expr_list); |
|
432
|
|
|
|
|
|
|
do $fName; |
|
433
|
|
|
|
|
|
|
if ($@) { |
|
434
|
|
|
|
|
|
|
print_error($@); |
|
435
|
|
|
|
|
|
|
} |
|
436
|
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
%postponed_file = (); |
|
438
|
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
restore_breakpoints_from_save($files); |
|
440
|
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
# Don't load saved watches against |
|
442
|
|
|
|
|
|
|
my %h = map { $_->{name} => 1 } @watch_exprs; |
|
443
|
|
|
|
|
|
|
foreach $rh (@$expr_list) { |
|
444
|
|
|
|
|
|
|
push @watch_exprs, {name => $rh->{name}} unless exists($h{$rh->{name}}); |
|
445
|
|
|
|
|
|
|
} |
|
446
|
|
|
|
|
|
|
$update_watch_list = 1; |
|
447
|
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
if ($current_source) { |
|
449
|
|
|
|
|
|
|
my $view = $current_source->view; |
|
450
|
|
|
|
|
|
|
$view->intellidraw if (defined $view); |
|
451
|
|
|
|
|
|
|
} |
|
452
|
|
|
|
|
|
|
} |
|
453
|
|
|
|
|
|
|
} # end of Restore State |
|
454
|
|
|
|
|
|
|
|
|
455
|
|
|
|
|
|
|
# |
|
456
|
|
|
|
|
|
|
# Save watches and breakpoints to state filename(it is param) |
|
457
|
|
|
|
|
|
|
# |
|
458
|
|
|
|
|
|
|
sub save_state_file { |
|
459
|
|
|
|
|
|
|
my ($fname) = @_; |
|
460
|
|
|
|
|
|
|
my ($files, $d, $saveStr); |
|
461
|
|
|
|
|
|
|
|
|
462
|
|
|
|
|
|
|
$files = breakpoints_to_save(); |
|
463
|
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
$d = Data::Dumper->new([$files, \@watch_exprs], [qw(files expr_list)]); |
|
465
|
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
$d->Indent(1); |
|
467
|
|
|
|
|
|
|
$d->Purity(1); |
|
468
|
|
|
|
|
|
|
$d->Terse(0); |
|
469
|
|
|
|
|
|
|
if (Data::Dumper->can('Dumpxs')) { |
|
470
|
|
|
|
|
|
|
$saveStr = $d->Dumpxs(); |
|
471
|
|
|
|
|
|
|
} else { |
|
472
|
|
|
|
|
|
|
$saveStr = $d->Dump(); |
|
473
|
|
|
|
|
|
|
} |
|
474
|
|
|
|
|
|
|
|
|
475
|
|
|
|
|
|
|
local (*F); |
|
476
|
|
|
|
|
|
|
open F, ">$fname" || die "Couldn't open file $fname"; |
|
477
|
|
|
|
|
|
|
print F $saveStr || die "Couldn't write file"; |
|
478
|
|
|
|
|
|
|
close F; |
|
479
|
|
|
|
|
|
|
} # end of save_state_file |
|
480
|
|
|
|
|
|
|
|
|
481
|
|
|
|
|
|
|
my $_log_opened = 0; |
|
482
|
|
|
|
|
|
|
|
|
483
|
|
|
|
|
|
|
# |
|
484
|
|
|
|
|
|
|
# Internal method for printing anything to file |
|
485
|
|
|
|
|
|
|
# 1. name of text |
|
486
|
|
|
|
|
|
|
# 2. variable |
|
487
|
|
|
|
|
|
|
# |
|
488
|
|
|
|
|
|
|
sub log_dumper { |
|
489
|
|
|
|
|
|
|
my ($name, $a) = @_; |
|
490
|
|
|
|
|
|
|
|
|
491
|
|
|
|
|
|
|
my $fDUMP = config_file("dump"); |
|
492
|
|
|
|
|
|
|
local (*W); |
|
493
|
|
|
|
|
|
|
open(W, ($_log_opened ? ">" : "") . ">$fDUMP") |
|
494
|
|
|
|
|
|
|
or die "Can't open dump file : $fDUMP\n"; |
|
495
|
|
|
|
|
|
|
$_log_opened = 1; |
|
496
|
|
|
|
|
|
|
print W "$name"; |
|
497
|
|
|
|
|
|
|
|
|
498
|
|
|
|
|
|
|
if ($a) { |
|
499
|
|
|
|
|
|
|
local $Data::Dumper::Purity = 0; |
|
500
|
|
|
|
|
|
|
local $Data::Dumper::Terse = 0; |
|
501
|
|
|
|
|
|
|
local $Data::Dumper::Indent = 2; |
|
502
|
|
|
|
|
|
|
local $Data::Dumper::Sortkeys = 1; |
|
503
|
|
|
|
|
|
|
print W Dumper($a); |
|
504
|
|
|
|
|
|
|
} |
|
505
|
|
|
|
|
|
|
print W "\n"; |
|
506
|
|
|
|
|
|
|
close(W); |
|
507
|
|
|
|
|
|
|
} |
|
508
|
|
|
|
|
|
|
|
|
509
|
|
|
|
|
|
|
# |
|
510
|
|
|
|
|
|
|
# UI for exiting |
|
511
|
|
|
|
|
|
|
# |
|
512
|
|
|
|
|
|
|
sub ui_db_quit { |
|
513
|
|
|
|
|
|
|
return |
|
514
|
|
|
|
|
|
|
if not $cui->dialog( |
|
515
|
|
|
|
|
|
|
-title => 'Quit Debugger', |
|
516
|
|
|
|
|
|
|
-buttons => ['yes', 'no'], |
|
517
|
|
|
|
|
|
|
-message => 'Do you really want to quit?', |
|
518
|
|
|
|
|
|
|
window_style(), |
|
519
|
|
|
|
|
|
|
); |
|
520
|
|
|
|
|
|
|
save_state_file(config_file("conf.rc")); |
|
521
|
|
|
|
|
|
|
|
|
522
|
|
|
|
|
|
|
$single = 0; |
|
523
|
|
|
|
|
|
|
for (my $i = 0; $i <= $stack_depth; ++$i) { |
|
524
|
|
|
|
|
|
|
$stack[$i] = 0; |
|
525
|
|
|
|
|
|
|
} |
|
526
|
|
|
|
|
|
|
|
|
527
|
|
|
|
|
|
|
$db_exit = 1; |
|
528
|
|
|
|
|
|
|
|
|
529
|
|
|
|
|
|
|
#print(STDERR $_, "\n") foreach (@compiled); |
|
530
|
|
|
|
|
|
|
exit(0); |
|
531
|
|
|
|
|
|
|
} |
|
532
|
|
|
|
|
|
|
|
|
533
|
|
|
|
|
|
|
sub db_cont { |
|
534
|
|
|
|
|
|
|
$new_single = 0; |
|
535
|
|
|
|
|
|
|
for (my $i = 0; $i <= $stack_depth; ++$i) { |
|
536
|
|
|
|
|
|
|
$stack[$i] &= ~1; |
|
537
|
|
|
|
|
|
|
} |
|
538
|
|
|
|
|
|
|
$yield = 1; |
|
539
|
|
|
|
|
|
|
} |
|
540
|
|
|
|
|
|
|
|
|
541
|
|
|
|
|
|
|
# |
|
542
|
|
|
|
|
|
|
# Key for step into method |
|
543
|
|
|
|
|
|
|
# |
|
544
|
|
|
|
|
|
|
sub db_step_in { |
|
545
|
|
|
|
|
|
|
$new_single = 1; |
|
546
|
|
|
|
|
|
|
$yield = 1; |
|
547
|
|
|
|
|
|
|
} |
|
548
|
|
|
|
|
|
|
|
|
549
|
|
|
|
|
|
|
# |
|
550
|
|
|
|
|
|
|
# Key for step over - next step |
|
551
|
|
|
|
|
|
|
# |
|
552
|
|
|
|
|
|
|
sub db_step_over { |
|
553
|
|
|
|
|
|
|
$new_single = 2; |
|
554
|
|
|
|
|
|
|
$yield = 1; |
|
555
|
|
|
|
|
|
|
} |
|
556
|
|
|
|
|
|
|
|
|
557
|
|
|
|
|
|
|
# |
|
558
|
|
|
|
|
|
|
# Key for step from given method |
|
559
|
|
|
|
|
|
|
# |
|
560
|
|
|
|
|
|
|
sub db_step_out { |
|
561
|
|
|
|
|
|
|
$new_single = 0; |
|
562
|
|
|
|
|
|
|
$stack[-1] &= ~1; |
|
563
|
|
|
|
|
|
|
$yield = 1; |
|
564
|
|
|
|
|
|
|
} |
|
565
|
|
|
|
|
|
|
|
|
566
|
|
|
|
|
|
|
# |
|
567
|
|
|
|
|
|
|
# $code is 0 or 1 and $r is ref to error string |
|
568
|
|
|
|
|
|
|
# 0 - Set breakpoint, If breakpoint exist on given line, than remove |
|
569
|
|
|
|
|
|
|
# 1 - Set breakpoint with condition |
|
570
|
|
|
|
|
|
|
# StringRef - Problem with condition in breakpoint, that reedit |
|
571
|
|
|
|
|
|
|
# |
|
572
|
|
|
|
|
|
|
sub db_toggle_break { |
|
573
|
|
|
|
|
|
|
my ($code, $r) = shift; |
|
574
|
|
|
|
|
|
|
local (*dbline) = $main::{'_<' . $current_source->filename}; |
|
575
|
|
|
|
|
|
|
$current_source->toggle_break($code, $r); |
|
576
|
|
|
|
|
|
|
} |
|
577
|
|
|
|
|
|
|
|
|
578
|
|
|
|
|
|
|
# |
|
579
|
|
|
|
|
|
|
# Add watch expression |
|
580
|
|
|
|
|
|
|
# |
|
581
|
|
|
|
|
|
|
sub db_add_watch_expr { |
|
582
|
|
|
|
|
|
|
my $text = shift; |
|
583
|
|
|
|
|
|
|
my $expr = $cui->question( |
|
584
|
|
|
|
|
|
|
-question => "Please enter an expression to watches\n" |
|
585
|
|
|
|
|
|
|
. "Global variables must be set as '\$main::varname'\n" |
|
586
|
|
|
|
|
|
|
. 'Array or Hash must set as Reference like \@a, otherwise show size', |
|
587
|
|
|
|
|
|
|
-title => "Add watch expresion", |
|
588
|
|
|
|
|
|
|
(defined($text) && length($text) ? (-answer => $text) : ()), |
|
589
|
|
|
|
|
|
|
window_style(), |
|
590
|
|
|
|
|
|
|
); |
|
591
|
|
|
|
|
|
|
if (defined($text) && length($text)) { |
|
592
|
|
|
|
|
|
|
my $pos = -1; |
|
593
|
|
|
|
|
|
|
for (my $i = 0; $pos == -1 && $i < scalar(@watch_exprs); $i++) { |
|
594
|
|
|
|
|
|
|
$pos = $i if ($watch_exprs[$i]->{name} eq $text); |
|
595
|
|
|
|
|
|
|
} |
|
596
|
|
|
|
|
|
|
splice(@watch_exprs, $pos, 1, {name => $expr}) if ($expr && $pos >= 0); |
|
597
|
|
|
|
|
|
|
} else { |
|
598
|
|
|
|
|
|
|
return if !$expr; |
|
599
|
|
|
|
|
|
|
push @watch_exprs, {name => $expr}; |
|
600
|
|
|
|
|
|
|
} |
|
601
|
|
|
|
|
|
|
$update_watch_list = 1; |
|
602
|
|
|
|
|
|
|
} |
|
603
|
|
|
|
|
|
|
|
|
604
|
|
|
|
|
|
|
sub db_edit_watch_expr { |
|
605
|
|
|
|
|
|
|
my $watch_list = shift; |
|
606
|
|
|
|
|
|
|
|
|
607
|
|
|
|
|
|
|
my $id = $watch_list->get_active_id; |
|
608
|
|
|
|
|
|
|
my $item = $watch_list->{-named_list}->[$id]; |
|
609
|
|
|
|
|
|
|
db_add_watch_expr($item->{name}); |
|
610
|
|
|
|
|
|
|
} |
|
611
|
|
|
|
|
|
|
|
|
612
|
|
|
|
|
|
|
# |
|
613
|
|
|
|
|
|
|
# List breapoints |
|
614
|
|
|
|
|
|
|
# |
|
615
|
|
|
|
|
|
|
sub ui_list_breakpoints { |
|
616
|
|
|
|
|
|
|
my @a = (); |
|
617
|
|
|
|
|
|
|
foreach my $file (keys %main::) { # file loop |
|
618
|
|
|
|
|
|
|
next unless $file =~ /^_ && exists $main::{$file}; |
|
619
|
|
|
|
|
|
|
|
|
620
|
|
|
|
|
|
|
local (*dbline) = $main::{$file}; |
|
621
|
|
|
|
|
|
|
while (my ($k, $d) = each %dbline) { |
|
622
|
|
|
|
|
|
|
next unless ($d); |
|
623
|
|
|
|
|
|
|
my $str = retfilename($file) . " line:$k "; |
|
624
|
|
|
|
|
|
|
if ($d =~ /\0/) { |
|
625
|
|
|
|
|
|
|
my ($s, $action) = split(/\0/, $d); |
|
626
|
|
|
|
|
|
|
$str .= "test ( $action )"; |
|
627
|
|
|
|
|
|
|
} |
|
628
|
|
|
|
|
|
|
push(@a, $str); |
|
629
|
|
|
|
|
|
|
} |
|
630
|
|
|
|
|
|
|
} # end of file loop |
|
631
|
|
|
|
|
|
|
|
|
632
|
|
|
|
|
|
|
my $filename = $cui->tempdialog( |
|
633
|
|
|
|
|
|
|
'Devel::PDB::Dialog::FileBrowser', |
|
634
|
|
|
|
|
|
|
-title => "List all breakpoints", |
|
635
|
|
|
|
|
|
|
-files => \@a, |
|
636
|
|
|
|
|
|
|
-its_breakpoints => 1, |
|
637
|
|
|
|
|
|
|
window_style(), |
|
638
|
|
|
|
|
|
|
); |
|
639
|
|
|
|
|
|
|
|
|
640
|
|
|
|
|
|
|
if ($filename) { |
|
641
|
|
|
|
|
|
|
my @a1 = split(" ", $filename); |
|
642
|
|
|
|
|
|
|
my @a2 = split(":", $a1[1]); |
|
643
|
|
|
|
|
|
|
my $source = $current_source = get_source($a1[0]); |
|
644
|
|
|
|
|
|
|
if ($source) { |
|
645
|
|
|
|
|
|
|
$sv->source($source); |
|
646
|
|
|
|
|
|
|
$sv->goto(int($a2[1]) + 1); |
|
647
|
|
|
|
|
|
|
} |
|
648
|
|
|
|
|
|
|
$sv->intellidraw; |
|
649
|
|
|
|
|
|
|
} else { |
|
650
|
|
|
|
|
|
|
clearalldblines (); |
|
651
|
|
|
|
|
|
|
|
|
652
|
|
|
|
|
|
|
my %h = (); |
|
653
|
|
|
|
|
|
|
foreach (@a) { |
|
654
|
|
|
|
|
|
|
my @a1 = split(" "); |
|
655
|
|
|
|
|
|
|
my @a2 = split(":", $a1[1]); |
|
656
|
|
|
|
|
|
|
|
|
657
|
|
|
|
|
|
|
my $fname = '_<' . $a1[0]; |
|
658
|
|
|
|
|
|
|
$h{$fname} = [] if (!exists($h{$fname})); |
|
659
|
|
|
|
|
|
|
push(@{$h{$fname}}, {line => $a2[1]}); |
|
660
|
|
|
|
|
|
|
} |
|
661
|
|
|
|
|
|
|
restore_breakpoints_from_save(\%h); |
|
662
|
|
|
|
|
|
|
$update_watch_list = 1; |
|
663
|
|
|
|
|
|
|
|
|
664
|
|
|
|
|
|
|
my $view = $current_source->view; |
|
665
|
|
|
|
|
|
|
$view->intellidraw if (defined $view); |
|
666
|
|
|
|
|
|
|
} |
|
667
|
|
|
|
|
|
|
} |
|
668
|
|
|
|
|
|
|
|
|
669
|
|
|
|
|
|
|
sub refresh_stack_menu { |
|
670
|
|
|
|
|
|
|
my ($str, $name, $i, $sub_offset, $subStack); |
|
671
|
|
|
|
|
|
|
|
|
672
|
|
|
|
|
|
|
# |
|
673
|
|
|
|
|
|
|
# CAUTION: In the effort to 'rationalize' the code |
|
674
|
|
|
|
|
|
|
# are moving some of this function down from DB::DB |
|
675
|
|
|
|
|
|
|
# to here. $sub_offset represents how far 'down' |
|
676
|
|
|
|
|
|
|
# we are from DB::DB. The $DB::subroutine_depth is |
|
677
|
|
|
|
|
|
|
# tracked in such a way that while we are 'in' the debugger |
|
678
|
|
|
|
|
|
|
# it will not be incremented, and thus represents the stack depth |
|
679
|
|
|
|
|
|
|
# of the target program. |
|
680
|
|
|
|
|
|
|
# |
|
681
|
|
|
|
|
|
|
$sub_offset = 1; |
|
682
|
|
|
|
|
|
|
$subStack = []; |
|
683
|
|
|
|
|
|
|
|
|
684
|
|
|
|
|
|
|
# clear existing entries |
|
685
|
|
|
|
|
|
|
for ($i = 0; $i <= ($DB::subroutine_depth || 0); $i++) { |
|
686
|
|
|
|
|
|
|
my @a = caller $i + $sub_offset; |
|
687
|
|
|
|
|
|
|
my ($package, $filename, $line, $subName) = caller $i + $sub_offset; |
|
688
|
|
|
|
|
|
|
last if !$subName; |
|
689
|
|
|
|
|
|
|
push @$subStack, {'name' => $subName, 'pck' => $package, 'filename' => $filename, 'line' => $line}; |
|
690
|
|
|
|
|
|
|
} |
|
691
|
|
|
|
|
|
|
|
|
692
|
|
|
|
|
|
|
#$self->{stack_menu}->menu->delete(0, 'last') ; # delete existing menu items |
|
693
|
|
|
|
|
|
|
#for( $i = 0 ; $subStack->[$i] ; $i++ ) { |
|
694
|
|
|
|
|
|
|
# $str = defined $subStack->[$i+1] ? "$subStack->[$i+1]->{name}" : "MAIN" ; |
|
695
|
|
|
|
|
|
|
# my ($f, $line) = ($subStack->[$i]->{filename}, $subStack->[$i]->{line}) ; # make copies of the values for use in 'sub' |
|
696
|
|
|
|
|
|
|
# $self->{stack_menu}->command(-label => $str, -command => sub { $self->goto_sub_from_stack($f, $line) ; } ) ; |
|
697
|
|
|
|
|
|
|
#} |
|
698
|
|
|
|
|
|
|
} # end of refresh_stack_menu |
|
699
|
|
|
|
|
|
|
|
|
700
|
|
|
|
|
|
|
# dump_trace(skip[,count]) |
|
701
|
|
|
|
|
|
|
# |
|
702
|
|
|
|
|
|
|
# Actually collect the traceback information available via C. It does |
|
703
|
|
|
|
|
|
|
# some filtering and cleanup of the data, but mostly it just collects it to |
|
704
|
|
|
|
|
|
|
# make C's job easier. |
|
705
|
|
|
|
|
|
|
# |
|
706
|
|
|
|
|
|
|
# C defines the number of stack frames to be skipped, working backwards |
|
707
|
|
|
|
|
|
|
# from the most current. C determines the total number of frames to |
|
708
|
|
|
|
|
|
|
# be returned; all of them (well, the first 10^9) are returned if C |
|
709
|
|
|
|
|
|
|
# is omitted. |
|
710
|
|
|
|
|
|
|
# |
|
711
|
|
|
|
|
|
|
# This routine returns a list of hashes, from most-recent to least-recent |
|
712
|
|
|
|
|
|
|
# stack frame. Each has the following keys and values: |
|
713
|
|
|
|
|
|
|
sub dump_trace { |
|
714
|
|
|
|
|
|
|
|
|
715
|
|
|
|
|
|
|
# How many levels to skip. |
|
716
|
|
|
|
|
|
|
my $skip = shift; |
|
717
|
|
|
|
|
|
|
|
|
718
|
|
|
|
|
|
|
# How many levels to show. (1e9 is a cheap way of saying "all of them"; |
|
719
|
|
|
|
|
|
|
# it's unlikely that we'll have more than a billion stack frames. If you |
|
720
|
|
|
|
|
|
|
# do, you've got an awfully big machine...) |
|
721
|
|
|
|
|
|
|
my $count = shift || 1e9; |
|
722
|
|
|
|
|
|
|
|
|
723
|
|
|
|
|
|
|
# We increment skip because caller(1) is the first level *back* from |
|
724
|
|
|
|
|
|
|
# the current one. Add $skip to the count of frames so we have a |
|
725
|
|
|
|
|
|
|
# simple stop criterion, counting from $skip to $count+$skip. |
|
726
|
|
|
|
|
|
|
$skip++; |
|
727
|
|
|
|
|
|
|
$count += $skip; |
|
728
|
|
|
|
|
|
|
|
|
729
|
|
|
|
|
|
|
# These variables are used to capture output from caller(); |
|
730
|
|
|
|
|
|
|
my ($p, $file, $line, $sub, $h, $context); |
|
731
|
|
|
|
|
|
|
|
|
732
|
|
|
|
|
|
|
my ($e, $r, @a, @sub, $args); |
|
733
|
|
|
|
|
|
|
|
|
734
|
|
|
|
|
|
|
#..... |
|
735
|
|
|
|
|
|
|
my @args = (); |
|
736
|
|
|
|
|
|
|
our $frame = 0; |
|
737
|
|
|
|
|
|
|
|
|
738
|
|
|
|
|
|
|
# XXX Okay... why'd we do that? |
|
739
|
|
|
|
|
|
|
my $nothard = not $frame & 8; |
|
740
|
|
|
|
|
|
|
local $frame = 0; |
|
741
|
|
|
|
|
|
|
|
|
742
|
|
|
|
|
|
|
# Do not want to trace this. |
|
743
|
|
|
|
|
|
|
my $otrace = $trace; |
|
744
|
|
|
|
|
|
|
$trace = 0; |
|
745
|
|
|
|
|
|
|
|
|
746
|
|
|
|
|
|
|
# Start out at the skip count. |
|
747
|
|
|
|
|
|
|
# If we haven't reached the number of frames requested, and caller() is |
|
748
|
|
|
|
|
|
|
# still returning something, stay in the loop. (If we pass the requested |
|
749
|
|
|
|
|
|
|
# number of stack frames, or we run out - caller() returns nothing - we |
|
750
|
|
|
|
|
|
|
# quit. |
|
751
|
|
|
|
|
|
|
# Up the stack frame index to go back one more level each time. |
|
752
|
|
|
|
|
|
|
for (my $i = $skip; $i < $count and ($p, $file, $line, $sub, $h, $context, $e, $r) = caller($i); $i++) { |
|
753
|
|
|
|
|
|
|
|
|
754
|
|
|
|
|
|
|
# Go through the arguments and save them for later. |
|
755
|
|
|
|
|
|
|
@a = (); |
|
756
|
|
|
|
|
|
|
for my $arg (@args) { |
|
757
|
|
|
|
|
|
|
my $type; |
|
758
|
|
|
|
|
|
|
if (not defined $arg) { # undefined parameter |
|
759
|
|
|
|
|
|
|
push @a, "undef"; |
|
760
|
|
|
|
|
|
|
} |
|
761
|
|
|
|
|
|
|
|
|
762
|
|
|
|
|
|
|
elsif ($nothard and tied $arg) { # tied parameter |
|
763
|
|
|
|
|
|
|
push @a, "tied"; |
|
764
|
|
|
|
|
|
|
} elsif ($nothard and $type = ref $arg) { # reference |
|
765
|
|
|
|
|
|
|
push @a, "ref($type)"; |
|
766
|
|
|
|
|
|
|
} else { # can be stringified |
|
767
|
|
|
|
|
|
|
local $_ = "$arg"; # Safe to stringify now - should not call f(). |
|
768
|
|
|
|
|
|
|
|
|
769
|
|
|
|
|
|
|
# Backslash any single-quotes or backslashes. |
|
770
|
|
|
|
|
|
|
s/([\'\\])/\\$1/g; |
|
771
|
|
|
|
|
|
|
|
|
772
|
|
|
|
|
|
|
# Single-quote it unless it's a number or a colon-separated |
|
773
|
|
|
|
|
|
|
# name. |
|
774
|
|
|
|
|
|
|
s/(.*)/'$1'/s |
|
775
|
|
|
|
|
|
|
unless /^(?: -?[\d.]+ | \*[\w:]* )$/x; |
|
776
|
|
|
|
|
|
|
|
|
777
|
|
|
|
|
|
|
# Turn high-bit characters into meta-whatever. |
|
778
|
|
|
|
|
|
|
s/([\200-\377])/sprintf("M-%c",ord($1)&0177)/eg; |
|
779
|
|
|
|
|
|
|
|
|
780
|
|
|
|
|
|
|
# Turn control characters into ^-whatever. |
|
781
|
|
|
|
|
|
|
s/([\0-\37\177])/sprintf("^%c",ord($1)^64)/eg; |
|
782
|
|
|
|
|
|
|
|
|
783
|
|
|
|
|
|
|
push(@a, $_); |
|
784
|
|
|
|
|
|
|
} ## end else [ if (not defined $arg) |
|
785
|
|
|
|
|
|
|
} ## end for $arg (@args) |
|
786
|
|
|
|
|
|
|
|
|
787
|
|
|
|
|
|
|
# If context is true, this is array (@)context. |
|
788
|
|
|
|
|
|
|
# If context is false, this is scalar ($) context. |
|
789
|
|
|
|
|
|
|
# If neither, context isn't defined. (This is apparently a 'can't |
|
790
|
|
|
|
|
|
|
# happen' trap.) |
|
791
|
|
|
|
|
|
|
$context = $context ? '@' : (defined $context ? "\$" : '.'); |
|
792
|
|
|
|
|
|
|
|
|
793
|
|
|
|
|
|
|
# if the sub has args ($h true), make an anonymous array of the |
|
794
|
|
|
|
|
|
|
# dumped args. |
|
795
|
|
|
|
|
|
|
$args = $h ? [@a] : undef; |
|
796
|
|
|
|
|
|
|
|
|
797
|
|
|
|
|
|
|
# remove trailing newline-whitespace-semicolon-end of line sequence |
|
798
|
|
|
|
|
|
|
# from the eval text, if any. |
|
799
|
|
|
|
|
|
|
$e =~ s/\n\s*\;\s*\Z// if $e; |
|
800
|
|
|
|
|
|
|
|
|
801
|
|
|
|
|
|
|
# Escape backslashed single-quotes again if necessary. |
|
802
|
|
|
|
|
|
|
$e =~ s/([\\\'])/\\$1/g if $e; |
|
803
|
|
|
|
|
|
|
|
|
804
|
|
|
|
|
|
|
# if the require flag is true, the eval text is from a require. |
|
805
|
|
|
|
|
|
|
if ($r) { |
|
806
|
|
|
|
|
|
|
$sub = "require '$e'"; |
|
807
|
|
|
|
|
|
|
} |
|
808
|
|
|
|
|
|
|
|
|
809
|
|
|
|
|
|
|
# if it's false, the eval text is really from an eval. |
|
810
|
|
|
|
|
|
|
elsif (defined $r) { |
|
811
|
|
|
|
|
|
|
$sub = "eval '$e'"; |
|
812
|
|
|
|
|
|
|
} |
|
813
|
|
|
|
|
|
|
|
|
814
|
|
|
|
|
|
|
# If the sub is '(eval)', this is a block eval, meaning we don't |
|
815
|
|
|
|
|
|
|
# know what the eval'ed text actually was. |
|
816
|
|
|
|
|
|
|
elsif ($sub eq '(eval)') { |
|
817
|
|
|
|
|
|
|
$sub = "eval {...}"; |
|
818
|
|
|
|
|
|
|
} |
|
819
|
|
|
|
|
|
|
|
|
820
|
|
|
|
|
|
|
# Stick the collected information into @sub as an anonymous hash. |
|
821
|
|
|
|
|
|
|
push( |
|
822
|
|
|
|
|
|
|
@sub, |
|
823
|
|
|
|
|
|
|
{ context => $context, |
|
824
|
|
|
|
|
|
|
sub => $sub, |
|
825
|
|
|
|
|
|
|
args => $args, |
|
826
|
|
|
|
|
|
|
file => $file, |
|
827
|
|
|
|
|
|
|
line => $line |
|
828
|
|
|
|
|
|
|
}); |
|
829
|
|
|
|
|
|
|
|
|
830
|
|
|
|
|
|
|
# Stop processing frames if the user hit control-C. |
|
831
|
|
|
|
|
|
|
last if $signal; |
|
832
|
|
|
|
|
|
|
} ## end for ($i = $skip ; $i < ... |
|
833
|
|
|
|
|
|
|
|
|
834
|
|
|
|
|
|
|
# Restore the trace value again. |
|
835
|
|
|
|
|
|
|
$trace = $otrace; |
|
836
|
|
|
|
|
|
|
@sub; |
|
837
|
|
|
|
|
|
|
} ## end sub dump_trace |
|
838
|
|
|
|
|
|
|
|
|
839
|
|
|
|
|
|
|
# |
|
840
|
|
|
|
|
|
|
# List of stack - methods call |
|
841
|
|
|
|
|
|
|
# |
|
842
|
|
|
|
|
|
|
sub ui_view_stack { |
|
843
|
|
|
|
|
|
|
my $rev = shift; |
|
844
|
|
|
|
|
|
|
|
|
845
|
|
|
|
|
|
|
my $i = -1; |
|
846
|
|
|
|
|
|
|
my @a = (); |
|
847
|
|
|
|
|
|
|
my %h = (); |
|
848
|
|
|
|
|
|
|
my %h_ret = (); |
|
849
|
|
|
|
|
|
|
foreach my $rh (dump_trace(2)) { |
|
850
|
|
|
|
|
|
|
if ($rh->{'sub'} =~ /DB::DB/) { |
|
851
|
|
|
|
|
|
|
$i = 1; |
|
852
|
|
|
|
|
|
|
next; |
|
853
|
|
|
|
|
|
|
} elsif ($i < 0) { |
|
854
|
|
|
|
|
|
|
next; |
|
855
|
|
|
|
|
|
|
} |
|
856
|
|
|
|
|
|
|
push(@a, $i); |
|
857
|
|
|
|
|
|
|
$h{$i} = |
|
858
|
|
|
|
|
|
|
$rh->{'sub'} . "(" |
|
859
|
|
|
|
|
|
|
. (ref($rh->{args}) eq "ARRAY" ? join(",", @{$rh->{args}}) : "") |
|
860
|
|
|
|
|
|
|
. ") in file " |
|
861
|
|
|
|
|
|
|
. $rh->{file} . ":" |
|
862
|
|
|
|
|
|
|
. $rh->{line}; |
|
863
|
|
|
|
|
|
|
$h_ret{$i} = $rh; |
|
864
|
|
|
|
|
|
|
$i++; |
|
865
|
|
|
|
|
|
|
} |
|
866
|
|
|
|
|
|
|
|
|
867
|
|
|
|
|
|
|
@a = reverse @a; |
|
868
|
|
|
|
|
|
|
my $win = $cui->add( |
|
869
|
|
|
|
|
|
|
'winstackwindow', 'Window', |
|
870
|
|
|
|
|
|
|
-padtop => 1, |
|
871
|
|
|
|
|
|
|
-border => 0, |
|
872
|
|
|
|
|
|
|
-centered => 1, |
|
873
|
|
|
|
|
|
|
-title => 'Stack', |
|
874
|
|
|
|
|
|
|
window_style(), |
|
875
|
|
|
|
|
|
|
); |
|
876
|
|
|
|
|
|
|
my $listbox = $win->add( |
|
877
|
|
|
|
|
|
|
'StackWindow', 'Listbox', |
|
878
|
|
|
|
|
|
|
-title => "Stack window", |
|
879
|
|
|
|
|
|
|
-y => 0, |
|
880
|
|
|
|
|
|
|
-border => 1, |
|
881
|
|
|
|
|
|
|
-padbottom => 1, |
|
882
|
|
|
|
|
|
|
|
|
883
|
|
|
|
|
|
|
#-width => $cui->canvaswidth, |
|
884
|
|
|
|
|
|
|
-vscrollbar => 1, |
|
885
|
|
|
|
|
|
|
-values => \@a, |
|
886
|
|
|
|
|
|
|
-labels => \%h, |
|
887
|
|
|
|
|
|
|
|
|
888
|
|
|
|
|
|
|
#-onselchange => \&on_file_active, |
|
889
|
|
|
|
|
|
|
window_style(), |
|
890
|
|
|
|
|
|
|
); |
|
891
|
|
|
|
|
|
|
$win->add( |
|
892
|
|
|
|
|
|
|
"help", "Label", |
|
893
|
|
|
|
|
|
|
-y => -1, |
|
894
|
|
|
|
|
|
|
-width => -1, |
|
895
|
|
|
|
|
|
|
-reverse => 1, |
|
896
|
|
|
|
|
|
|
-paddingspaces => 1, |
|
897
|
|
|
|
|
|
|
-text => " Ctrl+Q|Ctrl+C|F10|ESC - Exit | Ctrl+R|F2 - Reverse | Return - jump to given function " |
|
898
|
|
|
|
|
|
|
); |
|
899
|
|
|
|
|
|
|
$listbox->set_routine( |
|
900
|
|
|
|
|
|
|
'option-select', |
|
901
|
|
|
|
|
|
|
sub { |
|
902
|
|
|
|
|
|
|
my $this = shift; |
|
903
|
|
|
|
|
|
|
|
|
904
|
|
|
|
|
|
|
#$this->{-id_value} = $this->get_active_value; |
|
905
|
|
|
|
|
|
|
$this->loose_focus; |
|
906
|
|
|
|
|
|
|
}); |
|
907
|
|
|
|
|
|
|
|
|
908
|
|
|
|
|
|
|
$listbox->set_binding(sub { shift->loose_focus; }, "\cQ", "\cC", KEY_F(10), CUI_ESCAPE()); |
|
909
|
|
|
|
|
|
|
|
|
910
|
|
|
|
|
|
|
$listbox->set_binding(sub { my $this = shift; my @ar = reverse @a; $this->values(\@ar); }, "\cR", KEY_F(2)); |
|
911
|
|
|
|
|
|
|
|
|
912
|
|
|
|
|
|
|
my $sel = $listbox->modalfocus(); |
|
913
|
|
|
|
|
|
|
my $ia = $sel ? $sel->get_active_value() : undef; |
|
914
|
|
|
|
|
|
|
$win->delete("StackWindow"); |
|
915
|
|
|
|
|
|
|
$cui->delete("winstackwindow"); |
|
916
|
|
|
|
|
|
|
|
|
917
|
|
|
|
|
|
|
if ($ia) { |
|
918
|
|
|
|
|
|
|
my $source = $current_source = get_source($h_ret{$ia}->{file}); |
|
919
|
|
|
|
|
|
|
$sv->source($source) if $source; |
|
920
|
|
|
|
|
|
|
$sv->intellidraw; |
|
921
|
|
|
|
|
|
|
$sv->goto($h_ret{$ia}->{line} + 1); |
|
922
|
|
|
|
|
|
|
} |
|
923
|
|
|
|
|
|
|
|
|
924
|
|
|
|
|
|
|
$sv_win->focus; |
|
925
|
|
|
|
|
|
|
} |
|
926
|
|
|
|
|
|
|
|
|
927
|
|
|
|
|
|
|
# |
|
928
|
|
|
|
|
|
|
# UI export information |
|
929
|
|
|
|
|
|
|
# |
|
930
|
|
|
|
|
|
|
sub ui_db_export { |
|
931
|
|
|
|
|
|
|
my $win = $cui->add( |
|
932
|
|
|
|
|
|
|
'winexportwindow', 'Window', |
|
933
|
|
|
|
|
|
|
-border => 1, |
|
934
|
|
|
|
|
|
|
-centered => 1, |
|
935
|
|
|
|
|
|
|
-title => 'Export information from actuall position to file', |
|
936
|
|
|
|
|
|
|
-height => 14, |
|
937
|
|
|
|
|
|
|
window_style(), |
|
938
|
|
|
|
|
|
|
); |
|
939
|
|
|
|
|
|
|
|
|
940
|
|
|
|
|
|
|
$win->add("ExportLabel_1", 'Label', -y => 1, -x => 2, -text => 'Number of lines : ', -bold => 1); |
|
941
|
|
|
|
|
|
|
|
|
942
|
|
|
|
|
|
|
my $lines = 10; |
|
943
|
|
|
|
|
|
|
$win->add( |
|
944
|
|
|
|
|
|
|
"ExportNumber", "TextEntry", |
|
945
|
|
|
|
|
|
|
-y => 1, |
|
946
|
|
|
|
|
|
|
-x => 20, |
|
947
|
|
|
|
|
|
|
-width => 20, |
|
948
|
|
|
|
|
|
|
-text => $lines, |
|
949
|
|
|
|
|
|
|
-regexp => '/^\d*$/', |
|
950
|
|
|
|
|
|
|
-onchange => sub { $lines = shift->get(); }, |
|
951
|
|
|
|
|
|
|
); |
|
952
|
|
|
|
|
|
|
|
|
953
|
|
|
|
|
|
|
$win->add("ExportLabel_2", 'Label', -y => 3, -x => 2, -text => 'Filename : ', -bold => 1); |
|
954
|
|
|
|
|
|
|
|
|
955
|
|
|
|
|
|
|
my $filename = undef; |
|
956
|
|
|
|
|
|
|
$win->add( |
|
957
|
|
|
|
|
|
|
"ExportFilename", "TextEntry", |
|
958
|
|
|
|
|
|
|
-y => 3, |
|
959
|
|
|
|
|
|
|
-x => 14, |
|
960
|
|
|
|
|
|
|
-width => 30, |
|
961
|
|
|
|
|
|
|
-onchange => sub { $filename = shift->get(); }, |
|
962
|
|
|
|
|
|
|
); |
|
963
|
|
|
|
|
|
|
|
|
964
|
|
|
|
|
|
|
$win->add( |
|
965
|
|
|
|
|
|
|
"ExportLabel_3", 'Label', |
|
966
|
|
|
|
|
|
|
-y => 5, |
|
967
|
|
|
|
|
|
|
-x => 2, |
|
968
|
|
|
|
|
|
|
-text => 'Variables separated by space or export everything : ', |
|
969
|
|
|
|
|
|
|
-bold => 1, |
|
970
|
|
|
|
|
|
|
); |
|
971
|
|
|
|
|
|
|
my $variables = undef; |
|
972
|
|
|
|
|
|
|
$win->add( |
|
973
|
|
|
|
|
|
|
"ExportVariables", "TextEntry", |
|
974
|
|
|
|
|
|
|
-y => 6, |
|
975
|
|
|
|
|
|
|
-x => 2, |
|
976
|
|
|
|
|
|
|
-width => 30, |
|
977
|
|
|
|
|
|
|
-onchange => sub { $variables = shift->get(); }, |
|
978
|
|
|
|
|
|
|
); |
|
979
|
|
|
|
|
|
|
|
|
980
|
|
|
|
|
|
|
my $use_watches = 0; |
|
981
|
|
|
|
|
|
|
$win->add( |
|
982
|
|
|
|
|
|
|
'ExportWatches', 'Checkbox', |
|
983
|
|
|
|
|
|
|
-label => "Export all variables from watch tables", |
|
984
|
|
|
|
|
|
|
-y => 8, |
|
985
|
|
|
|
|
|
|
-x => 2, |
|
986
|
|
|
|
|
|
|
-onchange => sub { $use_watches = shift->get(); }, |
|
987
|
|
|
|
|
|
|
window_style(), |
|
988
|
|
|
|
|
|
|
); |
|
989
|
|
|
|
|
|
|
|
|
990
|
|
|
|
|
|
|
my $exit = 1; |
|
991
|
|
|
|
|
|
|
$win->add( |
|
992
|
|
|
|
|
|
|
'ExportButtons', |
|
993
|
|
|
|
|
|
|
'Buttonbox', |
|
994
|
|
|
|
|
|
|
-buttons => [{ |
|
995
|
|
|
|
|
|
|
-label => '< Ok >', |
|
996
|
|
|
|
|
|
|
-shortcut => 'o', |
|
997
|
|
|
|
|
|
|
-onpress => sub { $exit = 0; $win->loose_focus; } |
|
998
|
|
|
|
|
|
|
}, |
|
999
|
|
|
|
|
|
|
{ -label => '< Cancel >', |
|
1000
|
|
|
|
|
|
|
-shortcut => 'c', |
|
1001
|
|
|
|
|
|
|
-onpress => sub { |
|
1002
|
|
|
|
|
|
|
$win->loose_focus; |
|
1003
|
|
|
|
|
|
|
} |
|
1004
|
|
|
|
|
|
|
} |
|
1005
|
|
|
|
|
|
|
], |
|
1006
|
|
|
|
|
|
|
-y => 10, |
|
1007
|
|
|
|
|
|
|
-x => 2, |
|
1008
|
|
|
|
|
|
|
); |
|
1009
|
|
|
|
|
|
|
|
|
1010
|
|
|
|
|
|
|
$win->set_binding(sub { shift->loose_focus; }, "\cQ", "\cC", KEY_F(10), CUI_ESCAPE()); |
|
1011
|
|
|
|
|
|
|
my $sel = $win->modalfocus(); |
|
1012
|
|
|
|
|
|
|
$cui->delete("winexportwindow"); |
|
1013
|
|
|
|
|
|
|
|
|
1014
|
|
|
|
|
|
|
local *W; |
|
1015
|
|
|
|
|
|
|
if ($exit) { |
|
1016
|
|
|
|
|
|
|
} elsif (!$filename || !length($filename)) { |
|
1017
|
|
|
|
|
|
|
print_error("Filename must be set"); |
|
1018
|
|
|
|
|
|
|
} elsif (!open(W, ">$filename")) { |
|
1019
|
|
|
|
|
|
|
print_error("Can't open file $filename : $!"); |
|
1020
|
|
|
|
|
|
|
} else { |
|
1021
|
|
|
|
|
|
|
local (*dbline) = $main::{'_<' . $current_source->filename}; |
|
1022
|
|
|
|
|
|
|
|
|
1023
|
|
|
|
|
|
|
my $current_line = $current_source->current_line; |
|
1024
|
|
|
|
|
|
|
my $from = $current_line - $lines; |
|
1025
|
|
|
|
|
|
|
$from = 0 if ($from < 0); |
|
1026
|
|
|
|
|
|
|
my $to = $current_line + $lines; |
|
1027
|
|
|
|
|
|
|
my $l = length(sprintf("%d", $to)); |
|
1028
|
|
|
|
|
|
|
|
|
1029
|
|
|
|
|
|
|
print W "----- Filename : " . $current_source->filename . "----------\n"; |
|
1030
|
|
|
|
|
|
|
for my $i ($from .. $to) { |
|
1031
|
|
|
|
|
|
|
last unless exists $dbline[$i]; |
|
1032
|
|
|
|
|
|
|
if ($i == 0 && $dbline[$i] =~ /use\s+.*Devel::_?PDB/) { |
|
1033
|
|
|
|
|
|
|
$to++; |
|
1034
|
|
|
|
|
|
|
next; |
|
1035
|
|
|
|
|
|
|
} |
|
1036
|
|
|
|
|
|
|
printf W "%s%*d %s", $i == $current_line ? '*' : ' ', $l, $i, $dbline[$i]; |
|
1037
|
|
|
|
|
|
|
} |
|
1038
|
|
|
|
|
|
|
|
|
1039
|
|
|
|
|
|
|
sub print_variables { |
|
1040
|
|
|
|
|
|
|
my ($rh) = @_; |
|
1041
|
|
|
|
|
|
|
print W $rh->{name} . " -> " . $rh->{long_value} . "\n"; |
|
1042
|
|
|
|
|
|
|
} |
|
1043
|
|
|
|
|
|
|
print W "----- Stack : -------------\n"; |
|
1044
|
|
|
|
|
|
|
my %h = (); |
|
1045
|
|
|
|
|
|
|
%h = map { $_ => 1 } split(" ", $variables) if (length($variables)); |
|
1046
|
|
|
|
|
|
|
foreach my $rh (@padlist_disp) { |
|
1047
|
|
|
|
|
|
|
print_variables($rh) if (!keys(%h) || exists($h{$rh->{name}})); |
|
1048
|
|
|
|
|
|
|
} |
|
1049
|
|
|
|
|
|
|
|
|
1050
|
|
|
|
|
|
|
if ($use_watches) { |
|
1051
|
|
|
|
|
|
|
print W "----- Watches : -----------\n"; |
|
1052
|
|
|
|
|
|
|
foreach my $rh (@watch_exprs) { |
|
1053
|
|
|
|
|
|
|
print_variables($rh); |
|
1054
|
|
|
|
|
|
|
} |
|
1055
|
|
|
|
|
|
|
} |
|
1056
|
|
|
|
|
|
|
|
|
1057
|
|
|
|
|
|
|
close(W); |
|
1058
|
|
|
|
|
|
|
} |
|
1059
|
|
|
|
|
|
|
|
|
1060
|
|
|
|
|
|
|
$sv_win->focus; |
|
1061
|
|
|
|
|
|
|
} |
|
1062
|
|
|
|
|
|
|
|
|
1063
|
|
|
|
|
|
|
# |
|
1064
|
|
|
|
|
|
|
# UI open file |
|
1065
|
|
|
|
|
|
|
# |
|
1066
|
|
|
|
|
|
|
sub ui_open_file { |
|
1067
|
|
|
|
|
|
|
my ($title, $files) = @_; |
|
1068
|
|
|
|
|
|
|
|
|
1069
|
|
|
|
|
|
|
my $filename = $cui->tempdialog( |
|
1070
|
|
|
|
|
|
|
'Devel::PDB::Dialog::FileBrowser', |
|
1071
|
|
|
|
|
|
|
-title => $title, |
|
1072
|
|
|
|
|
|
|
-files => $files, |
|
1073
|
|
|
|
|
|
|
window_style(), |
|
1074
|
|
|
|
|
|
|
); |
|
1075
|
|
|
|
|
|
|
if ($filename) { |
|
1076
|
|
|
|
|
|
|
my $source = $current_source = get_source($filename); |
|
1077
|
|
|
|
|
|
|
$sv->source($source) if $source; |
|
1078
|
|
|
|
|
|
|
$sv->intellidraw; |
|
1079
|
|
|
|
|
|
|
} |
|
1080
|
|
|
|
|
|
|
} |
|
1081
|
|
|
|
|
|
|
|
|
1082
|
|
|
|
|
|
|
# |
|
1083
|
|
|
|
|
|
|
# UI view STD[OUT|ERR] files |
|
1084
|
|
|
|
|
|
|
# |
|
1085
|
|
|
|
|
|
|
sub db_view_std_files { |
|
1086
|
|
|
|
|
|
|
my ($use_exit) = @_; |
|
1087
|
|
|
|
|
|
|
my @ab = ({ |
|
1088
|
|
|
|
|
|
|
-label => '< STDOUT >', |
|
1089
|
|
|
|
|
|
|
-value => 1, |
|
1090
|
|
|
|
|
|
|
-shortcut => 'o' |
|
1091
|
|
|
|
|
|
|
}, |
|
1092
|
|
|
|
|
|
|
{ -label => '< STDERR >', |
|
1093
|
|
|
|
|
|
|
-value => 2, |
|
1094
|
|
|
|
|
|
|
-shortcut => 'e' |
|
1095
|
|
|
|
|
|
|
}); |
|
1096
|
|
|
|
|
|
|
unshift( |
|
1097
|
|
|
|
|
|
|
@ab, |
|
1098
|
|
|
|
|
|
|
{ -label => '< Exit >', |
|
1099
|
|
|
|
|
|
|
-value => -1, |
|
1100
|
|
|
|
|
|
|
-shortcut => 'x' |
|
1101
|
|
|
|
|
|
|
}) if ($use_exit); |
|
1102
|
|
|
|
|
|
|
|
|
1103
|
|
|
|
|
|
|
my $t = $cui->dialog( |
|
1104
|
|
|
|
|
|
|
-title => 'Open STD* files', |
|
1105
|
|
|
|
|
|
|
-buttons => \@ab, |
|
1106
|
|
|
|
|
|
|
-message => 'Choose which STD* file to open it?', |
|
1107
|
|
|
|
|
|
|
window_style(), |
|
1108
|
|
|
|
|
|
|
); |
|
1109
|
|
|
|
|
|
|
return if ($t == -1); |
|
1110
|
|
|
|
|
|
|
|
|
1111
|
|
|
|
|
|
|
my $text = ""; |
|
1112
|
|
|
|
|
|
|
if (open F, "<" . config_file($t == 2 ? "stderr" : "stdout")) { |
|
1113
|
|
|
|
|
|
|
while () { $text .= $_ } |
|
1114
|
|
|
|
|
|
|
close F; |
|
1115
|
|
|
|
|
|
|
} else { |
|
1116
|
|
|
|
|
|
|
$cui->error(-message => "Cannot read file " . config_file($t == 2 ? "stderr" : "stdout") . ":\n$!"); |
|
1117
|
|
|
|
|
|
|
exit(127); |
|
1118
|
|
|
|
|
|
|
} |
|
1119
|
|
|
|
|
|
|
my $win = $cui->add( |
|
1120
|
|
|
|
|
|
|
'winmytextviewer', 'Window', |
|
1121
|
|
|
|
|
|
|
-border => 0, |
|
1122
|
|
|
|
|
|
|
-title => 'Source', |
|
1123
|
|
|
|
|
|
|
window_style(), |
|
1124
|
|
|
|
|
|
|
); |
|
1125
|
|
|
|
|
|
|
my $textviewer = $win->add( |
|
1126
|
|
|
|
|
|
|
"mytextviewer", "TextViewer", |
|
1127
|
|
|
|
|
|
|
-homeonblur => 1, # cursor to homepos on blur? |
|
1128
|
|
|
|
|
|
|
-fg => -1, |
|
1129
|
|
|
|
|
|
|
-bg => -1, |
|
1130
|
|
|
|
|
|
|
-cursor => 1, |
|
1131
|
|
|
|
|
|
|
-border => 1, |
|
1132
|
|
|
|
|
|
|
-padtop => 0, |
|
1133
|
|
|
|
|
|
|
-padbottom => 1, |
|
1134
|
|
|
|
|
|
|
-showlines => 0, |
|
1135
|
|
|
|
|
|
|
-sbborder => 0, |
|
1136
|
|
|
|
|
|
|
-vscrollbar => 1, |
|
1137
|
|
|
|
|
|
|
-hscrollbar => 1, |
|
1138
|
|
|
|
|
|
|
-showhardreturns => 0, |
|
1139
|
|
|
|
|
|
|
-wrapping => 0, # wrapping slows down the editor :-( |
|
1140
|
|
|
|
|
|
|
-text => $text, |
|
1141
|
|
|
|
|
|
|
-title => " Viewing file STD" . ($t == 2 ? "ERR" : "OUT") . " : " . config_file($t == 2 ? "stderr" : "stdout"), |
|
1142
|
|
|
|
|
|
|
window_style(), |
|
1143
|
|
|
|
|
|
|
); |
|
1144
|
|
|
|
|
|
|
$win->add( |
|
1145
|
|
|
|
|
|
|
"help", "Label", |
|
1146
|
|
|
|
|
|
|
-y => -1, |
|
1147
|
|
|
|
|
|
|
-width => -1, |
|
1148
|
|
|
|
|
|
|
-reverse => 1, |
|
1149
|
|
|
|
|
|
|
-paddingspaces => 1, |
|
1150
|
|
|
|
|
|
|
-text => " Ctrl+Q|Ctrl+C|F10|ESC - Return " |
|
1151
|
|
|
|
|
|
|
); |
|
1152
|
|
|
|
|
|
|
$textviewer->set_binding(sub { shift->loose_focus; }, "\cQ", "\cC", KEY_F(10), CUI_ESCAPE()); |
|
1153
|
|
|
|
|
|
|
$textviewer->modalfocus(); |
|
1154
|
|
|
|
|
|
|
$win->delete("mytextviewer"); |
|
1155
|
|
|
|
|
|
|
$cui->delete("winmytextviewer"); |
|
1156
|
|
|
|
|
|
|
} |
|
1157
|
|
|
|
|
|
|
|
|
1158
|
|
|
|
|
|
|
# |
|
1159
|
|
|
|
|
|
|
# Change vertical size of windows. This change size of windows between Source and Watches+Stack |
|
1160
|
|
|
|
|
|
|
# 1 - decrease Source window |
|
1161
|
|
|
|
|
|
|
# -1 - increase Source window |
|
1162
|
|
|
|
|
|
|
# |
|
1163
|
|
|
|
|
|
|
sub ui_adjust_vert_parts { |
|
1164
|
|
|
|
|
|
|
my $delta = shift; |
|
1165
|
|
|
|
|
|
|
return |
|
1166
|
|
|
|
|
|
|
if $delta > 0 && $sv_win->{-padbottom} >= $cui->{-height} - $sv_win->{-padtop} - 5 |
|
1167
|
|
|
|
|
|
|
or $delta < 0 && $lower_win->{-height} <= 5; |
|
1168
|
|
|
|
|
|
|
$sv_win->{-padbottom} += $delta; |
|
1169
|
|
|
|
|
|
|
$lower_win->{-height} += $delta; |
|
1170
|
|
|
|
|
|
|
$cui->layout_contained_objects; |
|
1171
|
|
|
|
|
|
|
} |
|
1172
|
|
|
|
|
|
|
|
|
1173
|
|
|
|
|
|
|
# |
|
1174
|
|
|
|
|
|
|
# Change horizontal size of windows. This change size of windows between Watches expresion and Stack |
|
1175
|
|
|
|
|
|
|
# 1 - increasing Watches window |
|
1176
|
|
|
|
|
|
|
# -1 - decreasing Watches window |
|
1177
|
|
|
|
|
|
|
# |
|
1178
|
|
|
|
|
|
|
sub ui_adjust_hori_parts { |
|
1179
|
|
|
|
|
|
|
my $delta = shift; |
|
1180
|
|
|
|
|
|
|
return |
|
1181
|
|
|
|
|
|
|
if $delta > 0 && $auto_win->{-width} >= $cui->{-width} - 15 |
|
1182
|
|
|
|
|
|
|
or $delta < 0 && $auto_win->{-width} <= 15; |
|
1183
|
|
|
|
|
|
|
$auto_win->{-width} += $delta; |
|
1184
|
|
|
|
|
|
|
$watch_win->{-padleft} += $delta; |
|
1185
|
|
|
|
|
|
|
$cui->layout_contained_objects; |
|
1186
|
|
|
|
|
|
|
} |
|
1187
|
|
|
|
|
|
|
|
|
1188
|
|
|
|
|
|
|
# |
|
1189
|
|
|
|
|
|
|
# Return name for config file |
|
1190
|
|
|
|
|
|
|
# |
|
1191
|
|
|
|
|
|
|
sub config_file { |
|
1192
|
|
|
|
|
|
|
my $name = shift; |
|
1193
|
|
|
|
|
|
|
my $file_name = File::Basename::basename($Devel::PDB::scriptName); |
|
1194
|
|
|
|
|
|
|
my $dir_name = File::Basename::dirname(Cwd::abs_path($Devel::PDB::scriptName)); |
|
1195
|
|
|
|
|
|
|
if ($ENV{PDB_use_HOME} && exists($ENV{HOME})) { |
|
1196
|
|
|
|
|
|
|
$dir_name = $ENV{HOME} . "/.PDB"; |
|
1197
|
|
|
|
|
|
|
mkdir($dir_name) unless (-d $dir_name); |
|
1198
|
|
|
|
|
|
|
} |
|
1199
|
|
|
|
|
|
|
return $dir_name . "/.$file_name" . "-" . $name; |
|
1200
|
|
|
|
|
|
|
} |
|
1201
|
|
|
|
|
|
|
|
|
1202
|
|
|
|
|
|
|
my $keys_binded = undef; |
|
1203
|
|
|
|
|
|
|
my @keys_global = (); |
|
1204
|
|
|
|
|
|
|
my %keys_hash = (); |
|
1205
|
|
|
|
|
|
|
|
|
1206
|
|
|
|
|
|
|
# |
|
1207
|
|
|
|
|
|
|
# Set key |
|
1208
|
|
|
|
|
|
|
# 1 - CodeRef for appened action |
|
1209
|
|
|
|
|
|
|
# 2 - nickname for given action |
|
1210
|
|
|
|
|
|
|
# 3 - Text which will be printed |
|
1211
|
|
|
|
|
|
|
# 4 and others are keys for binding |
|
1212
|
|
|
|
|
|
|
# |
|
1213
|
|
|
|
|
|
|
sub set_key_binding($$@) { |
|
1214
|
|
|
|
|
|
|
my $rf = shift; |
|
1215
|
|
|
|
|
|
|
my $name = shift; |
|
1216
|
|
|
|
|
|
|
my $text = shift; |
|
1217
|
|
|
|
|
|
|
my @keys = @_; |
|
1218
|
|
|
|
|
|
|
|
|
1219
|
|
|
|
|
|
|
if (!defined($keys_binded)) { |
|
1220
|
|
|
|
|
|
|
if (open(my $fh, $ENV{HOME} . "/.PDB.keys")) { |
|
1221
|
|
|
|
|
|
|
while (<$fh>) { |
|
1222
|
|
|
|
|
|
|
chomp; |
|
1223
|
|
|
|
|
|
|
my @a = split("="); |
|
1224
|
|
|
|
|
|
|
next if (scalar(@a) < 2); |
|
1225
|
|
|
|
|
|
|
my @akeys = (); |
|
1226
|
|
|
|
|
|
|
foreach my $r (split(",", $a[1])) { |
|
1227
|
|
|
|
|
|
|
if ($r =~ /F/) { |
|
1228
|
|
|
|
|
|
|
$r =~ s/F//; |
|
1229
|
|
|
|
|
|
|
$r = KEY_F(int($r)); |
|
1230
|
|
|
|
|
|
|
} elsif ($r =~ /Control-/) { |
|
1231
|
|
|
|
|
|
|
$r =~ s/Control-//; |
|
1232
|
|
|
|
|
|
|
$r = chr(ord(uc($r)) & 0x1F); |
|
1233
|
|
|
|
|
|
|
} elsif ($r =~ /KEY_/) { |
|
1234
|
|
|
|
|
|
|
no strict; |
|
1235
|
|
|
|
|
|
|
$r = $Curses::{$r} ? &{"Curses::" . $r}() : undef; |
|
1236
|
|
|
|
|
|
|
} |
|
1237
|
|
|
|
|
|
|
push(@akeys, $r) if ($r); |
|
1238
|
|
|
|
|
|
|
} |
|
1239
|
|
|
|
|
|
|
$keys_binded->{$a[0]} = \@akeys; |
|
1240
|
|
|
|
|
|
|
} |
|
1241
|
|
|
|
|
|
|
close($fh); |
|
1242
|
|
|
|
|
|
|
} else { |
|
1243
|
|
|
|
|
|
|
$keys_binded = {}; |
|
1244
|
|
|
|
|
|
|
} |
|
1245
|
|
|
|
|
|
|
} |
|
1246
|
|
|
|
|
|
|
|
|
1247
|
|
|
|
|
|
|
push(@keys_global, {name => $text, key => \@keys}); |
|
1248
|
|
|
|
|
|
|
$cui->set_binding($rf, exists($keys_binded->{$name}) ? @{$keys_binded->{$name}} : @keys); |
|
1249
|
|
|
|
|
|
|
|
|
1250
|
|
|
|
|
|
|
$text .= " "; |
|
1251
|
|
|
|
|
|
|
foreach my $k (exists($keys_binded->{$name}) ? @{$keys_binded->{$name}} : @keys) { |
|
1252
|
|
|
|
|
|
|
my $key = $cui->key_to_ascii($k); |
|
1253
|
|
|
|
|
|
|
$text .= $key . " "; |
|
1254
|
|
|
|
|
|
|
|
|
1255
|
|
|
|
|
|
|
# Add duplicity |
|
1256
|
|
|
|
|
|
|
$keys_hash{$key} = [] unless (exists($keys_hash{$key})); |
|
1257
|
|
|
|
|
|
|
my $ra = $keys_hash{$key}; |
|
1258
|
|
|
|
|
|
|
push(@$ra, $name); |
|
1259
|
|
|
|
|
|
|
} |
|
1260
|
|
|
|
|
|
|
|
|
1261
|
|
|
|
|
|
|
return {-value => $rf, -label => $text}; |
|
1262
|
|
|
|
|
|
|
} |
|
1263
|
|
|
|
|
|
|
|
|
1264
|
|
|
|
|
|
|
sub val_unctrl { |
|
1265
|
|
|
|
|
|
|
local ($_) = @_; |
|
1266
|
|
|
|
|
|
|
|
|
1267
|
|
|
|
|
|
|
return \$_ if ref \$_ eq "GLOB"; |
|
1268
|
|
|
|
|
|
|
if (ord('A') == 193) { # EBCDIC. |
|
1269
|
|
|
|
|
|
|
# EBCDIC has no concept of "\cA" or "A" being related |
|
1270
|
|
|
|
|
|
|
# to each other by a linear/boolean mapping. |
|
1271
|
|
|
|
|
|
|
} else { |
|
1272
|
|
|
|
|
|
|
s/([\001-\037\177])/'^'.pack('c',ord($1)^64)/eg; |
|
1273
|
|
|
|
|
|
|
} |
|
1274
|
|
|
|
|
|
|
$_; |
|
1275
|
|
|
|
|
|
|
} |
|
1276
|
|
|
|
|
|
|
|
|
1277
|
|
|
|
|
|
|
# |
|
1278
|
|
|
|
|
|
|
# Window wieving or editing |
|
1279
|
|
|
|
|
|
|
# 1 - Editing program params |
|
1280
|
|
|
|
|
|
|
# 2 - Editing enviroment |
|
1281
|
|
|
|
|
|
|
# 3 - Viewing Perl special variables |
|
1282
|
|
|
|
|
|
|
# |
|
1283
|
|
|
|
|
|
|
sub ui_text_editor { |
|
1284
|
|
|
|
|
|
|
my $type = shift; |
|
1285
|
|
|
|
|
|
|
|
|
1286
|
|
|
|
|
|
|
my @rows = (); |
|
1287
|
|
|
|
|
|
|
my $str_title = ""; |
|
1288
|
|
|
|
|
|
|
my $str_label = ""; |
|
1289
|
|
|
|
|
|
|
my $use_editor = 1; |
|
1290
|
|
|
|
|
|
|
|
|
1291
|
|
|
|
|
|
|
if ($type == 1) { |
|
1292
|
|
|
|
|
|
|
@rows = @Devel::PDB::script_args; |
|
1293
|
|
|
|
|
|
|
$str_title = 'Edit program params'; |
|
1294
|
|
|
|
|
|
|
$str_label = " Enter => Save "; |
|
1295
|
|
|
|
|
|
|
} elsif ($type == 2) { |
|
1296
|
|
|
|
|
|
|
$str_title = 'Edit enviroments'; |
|
1297
|
|
|
|
|
|
|
$str_label = " F2 => Save "; |
|
1298
|
|
|
|
|
|
|
foreach my $k (sort keys %ENV) { |
|
1299
|
|
|
|
|
|
|
push(@rows, $k . "=" . $ENV{$k}); |
|
1300
|
|
|
|
|
|
|
} |
|
1301
|
|
|
|
|
|
|
} elsif ($type == 3) { |
|
1302
|
|
|
|
|
|
|
$str_title = 'View special variables'; |
|
1303
|
|
|
|
|
|
|
$use_editor = 0; |
|
1304
|
|
|
|
|
|
|
|
|
1305
|
|
|
|
|
|
|
sub rep_dumper { |
|
1306
|
|
|
|
|
|
|
my $s = shift; |
|
1307
|
|
|
|
|
|
|
$s =~ s/^\$//; |
|
1308
|
|
|
|
|
|
|
chomp($s); |
|
1309
|
|
|
|
|
|
|
return $s; |
|
1310
|
|
|
|
|
|
|
} |
|
1311
|
|
|
|
|
|
|
|
|
1312
|
|
|
|
|
|
|
no strict; |
|
1313
|
|
|
|
|
|
|
*stab = *{"main::"}; |
|
1314
|
|
|
|
|
|
|
foreach my $key (sort keys %stab) { |
|
1315
|
|
|
|
|
|
|
next if ($key =~ /^_); |
|
1316
|
|
|
|
|
|
|
local (*entry) = $stab{$key}; |
|
1317
|
|
|
|
|
|
|
|
|
1318
|
|
|
|
|
|
|
my $fileno; |
|
1319
|
|
|
|
|
|
|
|
|
1320
|
|
|
|
|
|
|
local $Data::Dumper::Purity = 0; |
|
1321
|
|
|
|
|
|
|
local $Data::Dumper::Terse = 0; |
|
1322
|
|
|
|
|
|
|
local $Data::Dumper::Indent = 2; |
|
1323
|
|
|
|
|
|
|
local $Data::Dumper::Sortkeys = 1; |
|
1324
|
|
|
|
|
|
|
if (defined $entry) { |
|
1325
|
|
|
|
|
|
|
push(@rows, '$' . &val_unctrl($key) . " = " . $entry); |
|
1326
|
|
|
|
|
|
|
} elsif (@entry) { |
|
1327
|
|
|
|
|
|
|
local $Data::Dumper::Varname = "\@$key"; |
|
1328
|
|
|
|
|
|
|
push(@rows, &rep_dumper(Dumper(@entry))); |
|
1329
|
|
|
|
|
|
|
} elsif ($key ne "main::" |
|
1330
|
|
|
|
|
|
|
&& $key ne "DB::" |
|
1331
|
|
|
|
|
|
|
&& %entry |
|
1332
|
|
|
|
|
|
|
&& $key !~ /::$/ |
|
1333
|
|
|
|
|
|
|
&& !($package eq "dumpvar" and $key eq "stab")) { |
|
1334
|
|
|
|
|
|
|
local $Data::Dumper::Varname = "\%$key"; |
|
1335
|
|
|
|
|
|
|
push(@rows, &rep_dumper(Dumper(%entry))); |
|
1336
|
|
|
|
|
|
|
} |
|
1337
|
|
|
|
|
|
|
} |
|
1338
|
|
|
|
|
|
|
} |
|
1339
|
|
|
|
|
|
|
|
|
1340
|
|
|
|
|
|
|
my $row = scalar(@rows) || 1; |
|
1341
|
|
|
|
|
|
|
|
|
1342
|
|
|
|
|
|
|
my $win = $cui->add( |
|
1343
|
|
|
|
|
|
|
'winChangeParams', 'Window', |
|
1344
|
|
|
|
|
|
|
-border => 1, |
|
1345
|
|
|
|
|
|
|
|
|
1346
|
|
|
|
|
|
|
#-y => int(($LINES - ($row + 3)) / 2), # Buggy |
|
1347
|
|
|
|
|
|
|
#-height => $row + 3, |
|
1348
|
|
|
|
|
|
|
-centered => 1, |
|
1349
|
|
|
|
|
|
|
-title => $str_title, |
|
1350
|
|
|
|
|
|
|
window_style(), |
|
1351
|
|
|
|
|
|
|
); |
|
1352
|
|
|
|
|
|
|
my $x = $win->add( |
|
1353
|
|
|
|
|
|
|
"ChangeParams", $use_editor ? "TextEditor" : "TextViewer", |
|
1354
|
|
|
|
|
|
|
-homeonblur => 1, # cursor to homepos on blur? |
|
1355
|
|
|
|
|
|
|
-fg => -1, |
|
1356
|
|
|
|
|
|
|
-bg => -1, |
|
1357
|
|
|
|
|
|
|
-cursor => 1, |
|
1358
|
|
|
|
|
|
|
-padbottom => 1, |
|
1359
|
|
|
|
|
|
|
-text => join("\n", @rows), |
|
1360
|
|
|
|
|
|
|
); |
|
1361
|
|
|
|
|
|
|
$win->add( |
|
1362
|
|
|
|
|
|
|
"help", "Label", |
|
1363
|
|
|
|
|
|
|
-y => -1, |
|
1364
|
|
|
|
|
|
|
-width => -1, |
|
1365
|
|
|
|
|
|
|
-reverse => 1, |
|
1366
|
|
|
|
|
|
|
-paddingspaces => 1, |
|
1367
|
|
|
|
|
|
|
-text => " Ctrl+Q|Ctrl+C|F10|ESC -> Return " . $str_label, |
|
1368
|
|
|
|
|
|
|
); |
|
1369
|
|
|
|
|
|
|
|
|
1370
|
|
|
|
|
|
|
# Setup bindings. |
|
1371
|
|
|
|
|
|
|
$x->clear_binding('loose-focus'); |
|
1372
|
|
|
|
|
|
|
$x->set_binding(sub { shift->loose_focus; }, "\cQ", "\cC", KEY_F(10), CUI_ESCAPE()); |
|
1373
|
|
|
|
|
|
|
|
|
1374
|
|
|
|
|
|
|
if ($type == 1) { |
|
1375
|
|
|
|
|
|
|
$x->set_binding( |
|
1376
|
|
|
|
|
|
|
sub { |
|
1377
|
|
|
|
|
|
|
my $this = shift; |
|
1378
|
|
|
|
|
|
|
@Devel::PDB::script_args = (); |
|
1379
|
|
|
|
|
|
|
foreach my $s (split("\n", $this->get())) { |
|
1380
|
|
|
|
|
|
|
my $x = $s; |
|
1381
|
|
|
|
|
|
|
$x =~ s/ //g; |
|
1382
|
|
|
|
|
|
|
push(@Devel::PDB::script_args, $s) if (length($x)); |
|
1383
|
|
|
|
|
|
|
} |
|
1384
|
|
|
|
|
|
|
$this->loose_focus; |
|
1385
|
|
|
|
|
|
|
}, |
|
1386
|
|
|
|
|
|
|
KEY_ENTER(), |
|
1387
|
|
|
|
|
|
|
KEY_BTAB(), |
|
1388
|
|
|
|
|
|
|
CUI_TAB()); |
|
1389
|
|
|
|
|
|
|
} elsif ($type == 2) { |
|
1390
|
|
|
|
|
|
|
$x->set_binding( |
|
1391
|
|
|
|
|
|
|
sub { |
|
1392
|
|
|
|
|
|
|
my $this = shift; |
|
1393
|
|
|
|
|
|
|
%ENV = (); |
|
1394
|
|
|
|
|
|
|
foreach my $s (split("\n", $this->get())) { |
|
1395
|
|
|
|
|
|
|
my $x = $s; |
|
1396
|
|
|
|
|
|
|
$x =~ s/ //g; |
|
1397
|
|
|
|
|
|
|
if (length($x)) { |
|
1398
|
|
|
|
|
|
|
my @a = split("=", $s); |
|
1399
|
|
|
|
|
|
|
$ENV{$a[0]} = $a[1] if (scalar(@a) == 2); |
|
1400
|
|
|
|
|
|
|
} |
|
1401
|
|
|
|
|
|
|
} |
|
1402
|
|
|
|
|
|
|
$this->loose_focus; |
|
1403
|
|
|
|
|
|
|
}, |
|
1404
|
|
|
|
|
|
|
KEY_F(2)); |
|
1405
|
|
|
|
|
|
|
} elsif ($type == 3) { |
|
1406
|
|
|
|
|
|
|
} |
|
1407
|
|
|
|
|
|
|
|
|
1408
|
|
|
|
|
|
|
$x->modalfocus(); |
|
1409
|
|
|
|
|
|
|
$win->delete('ChangeParams'); |
|
1410
|
|
|
|
|
|
|
$cui->delete('winChangeParams'); |
|
1411
|
|
|
|
|
|
|
$sv_win->focus; |
|
1412
|
|
|
|
|
|
|
} |
|
1413
|
|
|
|
|
|
|
|
|
1414
|
|
|
|
|
|
|
# |
|
1415
|
|
|
|
|
|
|
# Print helping keys association |
|
1416
|
|
|
|
|
|
|
# |
|
1417
|
|
|
|
|
|
|
sub ui_db_help { |
|
1418
|
|
|
|
|
|
|
my @a = (); |
|
1419
|
|
|
|
|
|
|
push(@a, "Global"); |
|
1420
|
|
|
|
|
|
|
foreach my $rh (@keys_global) { |
|
1421
|
|
|
|
|
|
|
my $s = " "; |
|
1422
|
|
|
|
|
|
|
foreach (@{$rh->{key}}) { |
|
1423
|
|
|
|
|
|
|
$s .= $cui->key_to_ascii($_) . " "; |
|
1424
|
|
|
|
|
|
|
} |
|
1425
|
|
|
|
|
|
|
push(@a, $s . "\t" . $rh->{name}); |
|
1426
|
|
|
|
|
|
|
} |
|
1427
|
|
|
|
|
|
|
|
|
1428
|
|
|
|
|
|
|
push(@a, "Source Code Window"); |
|
1429
|
|
|
|
|
|
|
push(@a, " UP/DOWN/LEFT/RIGHT/PAGE UP/PAGE DOWN\tMove the cursor"); |
|
1430
|
|
|
|
|
|
|
push(@a, " H/J/K/L/Ctrl+F/Ctrl+B\tIf you use VI, you will know"); |
|
1431
|
|
|
|
|
|
|
push(@a, " /\tSearch using a RegEx in the current opened file"); |
|
1432
|
|
|
|
|
|
|
push(@a, " n\tSearch Next"); |
|
1433
|
|
|
|
|
|
|
push(@a, " N\tSearch Previous"); |
|
1434
|
|
|
|
|
|
|
push(@a, " Ctrl+G\tGoto a specific line"); |
|
1435
|
|
|
|
|
|
|
|
|
1436
|
|
|
|
|
|
|
push(@a, "Lexical Variable Window / Watch Window"); |
|
1437
|
|
|
|
|
|
|
push(@a, " UP/DOWN\tMove the cursor"); |
|
1438
|
|
|
|
|
|
|
push(@a, " ENTER\tShow the Data::Dumper output of the highlighted item in a scrollable dialog"); |
|
1439
|
|
|
|
|
|
|
push(@a, " DEL\tRemove the highlighted expression (Watch Window only)"); |
|
1440
|
|
|
|
|
|
|
|
|
1441
|
|
|
|
|
|
|
push(@a, "Compiled File Dialog / Opened File Dialog"); |
|
1442
|
|
|
|
|
|
|
push(@a, " TAB\tToggle the focus between the file list and the filter"); |
|
1443
|
|
|
|
|
|
|
push(@a, " ENTER\tSelect the highlighted file or apply the filter to the file list"); |
|
1444
|
|
|
|
|
|
|
push(@a, "Other"); |
|
1445
|
|
|
|
|
|
|
push(@a, " Esc,F10\tBack,Exit function"); |
|
1446
|
|
|
|
|
|
|
push(@a, " Ctrl+S,Ctrl+L,F6\tExporting to file"); |
|
1447
|
|
|
|
|
|
|
|
|
1448
|
|
|
|
|
|
|
if (keys %keys_hash) { |
|
1449
|
|
|
|
|
|
|
my @ad = (); |
|
1450
|
|
|
|
|
|
|
foreach my $k (sort %keys_hash) { |
|
1451
|
|
|
|
|
|
|
next if (ref($k)); |
|
1452
|
|
|
|
|
|
|
my $ra = $keys_hash{$k}; |
|
1453
|
|
|
|
|
|
|
next if (scalar(@$ra) <= 1); |
|
1454
|
|
|
|
|
|
|
push(@ad, $k); |
|
1455
|
|
|
|
|
|
|
push(@ad, map { $_ } @$ra); |
|
1456
|
|
|
|
|
|
|
} |
|
1457
|
|
|
|
|
|
|
push(@a, " ", " ", "Duplicity in keys", " ", @ad) if (@ad); |
|
1458
|
|
|
|
|
|
|
} |
|
1459
|
|
|
|
|
|
|
|
|
1460
|
|
|
|
|
|
|
dialog_message( |
|
1461
|
|
|
|
|
|
|
-title => "Help Keys", |
|
1462
|
|
|
|
|
|
|
-message => join("\n", @a), |
|
1463
|
|
|
|
|
|
|
); |
|
1464
|
|
|
|
|
|
|
} |
|
1465
|
|
|
|
|
|
|
|
|
1466
|
|
|
|
|
|
|
# |
|
1467
|
|
|
|
|
|
|
# Create dialog message window with binded key F2 for saving text |
|
1468
|
|
|
|
|
|
|
# |
|
1469
|
|
|
|
|
|
|
sub dialog_message { |
|
1470
|
|
|
|
|
|
|
my %args = @_; |
|
1471
|
|
|
|
|
|
|
Devel::PDB::Dialog::Message->run(%args, window_style()); |
|
1472
|
|
|
|
|
|
|
} |
|
1473
|
|
|
|
|
|
|
|
|
1474
|
|
|
|
|
|
|
# |
|
1475
|
|
|
|
|
|
|
# Exporting to file |
|
1476
|
|
|
|
|
|
|
# |
|
1477
|
|
|
|
|
|
|
sub export_to_file { |
|
1478
|
|
|
|
|
|
|
my ($name, $title, $rh_str) = @_; |
|
1479
|
|
|
|
|
|
|
|
|
1480
|
|
|
|
|
|
|
return unless $cui; |
|
1481
|
|
|
|
|
|
|
$name ||= "Title"; |
|
1482
|
|
|
|
|
|
|
my $fname = $cui->question(-question => 'Add filename to export', DB::window_style()) || return; |
|
1483
|
|
|
|
|
|
|
if (open(my $fh, ">", $fname)) { |
|
1484
|
|
|
|
|
|
|
print $fh "----- $name : " . $title . " ----------\n" if ($title); |
|
1485
|
|
|
|
|
|
|
print $fh $$rh_str; |
|
1486
|
|
|
|
|
|
|
print $fh "\n"; |
|
1487
|
|
|
|
|
|
|
close($fh); |
|
1488
|
|
|
|
|
|
|
} else { |
|
1489
|
|
|
|
|
|
|
DB::print_error("Can't open file $fname : $!"); |
|
1490
|
|
|
|
|
|
|
} |
|
1491
|
|
|
|
|
|
|
} |
|
1492
|
|
|
|
|
|
|
|
|
1493
|
|
|
|
|
|
|
# |
|
1494
|
|
|
|
|
|
|
# Activate window |
|
1495
|
|
|
|
|
|
|
# |
|
1496
|
|
|
|
|
|
|
sub set_active_window { |
|
1497
|
|
|
|
|
|
|
my $win = shift; |
|
1498
|
|
|
|
|
|
|
|
|
1499
|
|
|
|
|
|
|
if ($win == 2) { |
|
1500
|
|
|
|
|
|
|
$ui_window_focused = 1; |
|
1501
|
|
|
|
|
|
|
$auto_win->focus; |
|
1502
|
|
|
|
|
|
|
} elsif ($win == 3) { |
|
1503
|
|
|
|
|
|
|
$ui_window_focused = 2; |
|
1504
|
|
|
|
|
|
|
|
|
1505
|
|
|
|
|
|
|
#ui_update_watch_list(); |
|
1506
|
|
|
|
|
|
|
$watch_win->focus; |
|
1507
|
|
|
|
|
|
|
} else { |
|
1508
|
|
|
|
|
|
|
$ui_window_focused = 0; |
|
1509
|
|
|
|
|
|
|
$sv_win->focus; |
|
1510
|
|
|
|
|
|
|
} |
|
1511
|
|
|
|
|
|
|
} |
|
1512
|
|
|
|
|
|
|
|
|
1513
|
|
|
|
|
|
|
# |
|
1514
|
|
|
|
|
|
|
# Initialize ncurses methods |
|
1515
|
|
|
|
|
|
|
# |
|
1516
|
|
|
|
|
|
|
sub init { |
|
1517
|
|
|
|
|
|
|
|
|
1518
|
|
|
|
|
|
|
# Set own colours |
|
1519
|
|
|
|
|
|
|
if (open(my $fh, $ENV{HOME} . "/.PDB.colours")) { |
|
1520
|
|
|
|
|
|
|
my %h; |
|
1521
|
|
|
|
|
|
|
while (<$fh>) { |
|
1522
|
|
|
|
|
|
|
chomp; |
|
1523
|
|
|
|
|
|
|
my @a = split(/\s+/); |
|
1524
|
|
|
|
|
|
|
$h{$a[0]} = $a[1]; |
|
1525
|
|
|
|
|
|
|
} |
|
1526
|
|
|
|
|
|
|
close($fh); |
|
1527
|
|
|
|
|
|
|
window_style(%h); |
|
1528
|
|
|
|
|
|
|
} |
|
1529
|
|
|
|
|
|
|
|
|
1530
|
|
|
|
|
|
|
# can anybody tell me why $win->notimeout(1) doesn't work? |
|
1531
|
|
|
|
|
|
|
$ENV{ESCDELAY} = '0'; |
|
1532
|
|
|
|
|
|
|
|
|
1533
|
|
|
|
|
|
|
$cui = new Curses::UI( |
|
1534
|
|
|
|
|
|
|
-clear_on_exit => 1, |
|
1535
|
|
|
|
|
|
|
-color_support => 1, |
|
1536
|
|
|
|
|
|
|
-mouse_support => 1, |
|
1537
|
|
|
|
|
|
|
); |
|
1538
|
|
|
|
|
|
|
|
|
1539
|
|
|
|
|
|
|
if ($Curses::UI::VERSION > 0.9602) { |
|
1540
|
|
|
|
|
|
|
|
|
1541
|
|
|
|
|
|
|
# In version 0.9603 has ben removed rootobject, but we need in this modules : |
|
1542
|
|
|
|
|
|
|
# - PDB/SourceView.pm |
|
1543
|
|
|
|
|
|
|
# - PDB/Dialog/Message.pm |
|
1544
|
|
|
|
|
|
|
$Curses::UI::rootobject = $cui; |
|
1545
|
|
|
|
|
|
|
} |
|
1546
|
|
|
|
|
|
|
|
|
1547
|
|
|
|
|
|
|
if ($Curses::UI::color_support) { |
|
1548
|
|
|
|
|
|
|
my $old_draw = \&Curses::UI::Widget::draw; |
|
1549
|
|
|
|
|
|
|
no warnings; |
|
1550
|
|
|
|
|
|
|
*Curses::UI::Widget::draw = sub (;$) { |
|
1551
|
|
|
|
|
|
|
my ($this) = @_; |
|
1552
|
|
|
|
|
|
|
if (defined $this->{-fg} && defined $this->{-bg}) { |
|
1553
|
|
|
|
|
|
|
my $canvas = |
|
1554
|
|
|
|
|
|
|
defined $this->{-borderscr} |
|
1555
|
|
|
|
|
|
|
? $this->{-borderscr} |
|
1556
|
|
|
|
|
|
|
: $this->{-canvasscr}; |
|
1557
|
|
|
|
|
|
|
$canvas->bkgdset(COLOR_PAIR($Curses::UI::color_object->get_color_pair($this->{-fg}, $this->{-bg}))); |
|
1558
|
|
|
|
|
|
|
} |
|
1559
|
|
|
|
|
|
|
&$old_draw(@_); |
|
1560
|
|
|
|
|
|
|
}; |
|
1561
|
|
|
|
|
|
|
} |
|
1562
|
|
|
|
|
|
|
|
|
1563
|
|
|
|
|
|
|
my $lower_height = int($cui->{-height} * 0.25); |
|
1564
|
|
|
|
|
|
|
my $half_width = int($cui->{-width} * 0.5); |
|
1565
|
|
|
|
|
|
|
|
|
1566
|
|
|
|
|
|
|
$sv_win = $cui->add( |
|
1567
|
|
|
|
|
|
|
'sv_win', 'Window', |
|
1568
|
|
|
|
|
|
|
-padtop => 1, |
|
1569
|
|
|
|
|
|
|
-padbottom => $lower_height, |
|
1570
|
|
|
|
|
|
|
-border => 0, |
|
1571
|
|
|
|
|
|
|
-ipad => 0, |
|
1572
|
|
|
|
|
|
|
-title => 'Source', |
|
1573
|
|
|
|
|
|
|
); |
|
1574
|
|
|
|
|
|
|
$sv = $sv_win->add( |
|
1575
|
|
|
|
|
|
|
'sv', 'Devel::PDB::SourceView', |
|
1576
|
|
|
|
|
|
|
-border => 1, |
|
1577
|
|
|
|
|
|
|
|
|
1578
|
|
|
|
|
|
|
#-padbottom => 3, |
|
1579
|
|
|
|
|
|
|
window_style(), |
|
1580
|
|
|
|
|
|
|
); |
|
1581
|
|
|
|
|
|
|
|
|
1582
|
|
|
|
|
|
|
$lower_win = $cui->add( |
|
1583
|
|
|
|
|
|
|
'lower_win', 'Window', |
|
1584
|
|
|
|
|
|
|
-border => 0, |
|
1585
|
|
|
|
|
|
|
-y => -1, |
|
1586
|
|
|
|
|
|
|
-height => $lower_height, |
|
1587
|
|
|
|
|
|
|
window_style(), |
|
1588
|
|
|
|
|
|
|
); |
|
1589
|
|
|
|
|
|
|
|
|
1590
|
|
|
|
|
|
|
$auto_win = $lower_win->add( |
|
1591
|
|
|
|
|
|
|
'auto_win', 'Window', |
|
1592
|
|
|
|
|
|
|
-border => 1, |
|
1593
|
|
|
|
|
|
|
-y => -1, |
|
1594
|
|
|
|
|
|
|
-width => $half_width, |
|
1595
|
|
|
|
|
|
|
-title => 'Auto', |
|
1596
|
|
|
|
|
|
|
window_style(), |
|
1597
|
|
|
|
|
|
|
); |
|
1598
|
|
|
|
|
|
|
$padvar_list = $auto_win->add( |
|
1599
|
|
|
|
|
|
|
'padvar_list', 'Devel::PDB::NamedListbox', |
|
1600
|
|
|
|
|
|
|
-readonly => 1, |
|
1601
|
|
|
|
|
|
|
-sort_key => 'name', |
|
1602
|
|
|
|
|
|
|
-named_list => \@padlist_disp, |
|
1603
|
|
|
|
|
|
|
); |
|
1604
|
|
|
|
|
|
|
$padvar_list->userdata($cui); |
|
1605
|
|
|
|
|
|
|
|
|
1606
|
|
|
|
|
|
|
$watch_win = $lower_win->add( |
|
1607
|
|
|
|
|
|
|
'watch_win', 'Window', |
|
1608
|
|
|
|
|
|
|
-border => 1, |
|
1609
|
|
|
|
|
|
|
-x => -1, |
|
1610
|
|
|
|
|
|
|
-y => -1, |
|
1611
|
|
|
|
|
|
|
-padleft => $half_width, |
|
1612
|
|
|
|
|
|
|
-title => 'Watch', |
|
1613
|
|
|
|
|
|
|
window_style(), |
|
1614
|
|
|
|
|
|
|
); |
|
1615
|
|
|
|
|
|
|
$watch_list = $watch_win->add( |
|
1616
|
|
|
|
|
|
|
'watch_list', 'Devel::PDB::NamedListbox', |
|
1617
|
|
|
|
|
|
|
|
|
1618
|
|
|
|
|
|
|
# -sort_key => 'name', # For sorting by name |
|
1619
|
|
|
|
|
|
|
-named_list => \@watch_exprs, |
|
1620
|
|
|
|
|
|
|
); |
|
1621
|
|
|
|
|
|
|
|
|
1622
|
|
|
|
|
|
|
my $fConfig = config_file("conf"); |
|
1623
|
|
|
|
|
|
|
|
|
1624
|
|
|
|
|
|
|
my @aFile = (); |
|
1625
|
|
|
|
|
|
|
my @aEdit = (); |
|
1626
|
|
|
|
|
|
|
my @aView = (); |
|
1627
|
|
|
|
|
|
|
my @aExecution = (); |
|
1628
|
|
|
|
|
|
|
my @aBreakpoint = (); |
|
1629
|
|
|
|
|
|
|
my @aSettings = (); |
|
1630
|
|
|
|
|
|
|
|
|
1631
|
|
|
|
|
|
|
set_key_binding(\&ui_db_help, "Keys", "Keys help", "\cK"); |
|
1632
|
|
|
|
|
|
|
set_key_binding(sub { shift->getobj('menu')->focus }, "Menu", "Main menu", KEY_F(10)); |
|
1633
|
|
|
|
|
|
|
|
|
1634
|
|
|
|
|
|
|
# Submenu - File |
|
1635
|
|
|
|
|
|
|
push(@aFile, set_key_binding(sub { db_view_std_files(0); $sv_win->focus; }, "ViewSTDFiles", "View STD* files", KEY_F(4))); |
|
1636
|
|
|
|
|
|
|
|
|
1637
|
|
|
|
|
|
|
push( |
|
1638
|
|
|
|
|
|
|
@aFile, |
|
1639
|
|
|
|
|
|
|
set_key_binding( |
|
1640
|
|
|
|
|
|
|
sub { |
|
1641
|
|
|
|
|
|
|
if ($ui_window_focused == 2) { |
|
1642
|
|
|
|
|
|
|
$update_watch_list = 1; |
|
1643
|
|
|
|
|
|
|
return; |
|
1644
|
|
|
|
|
|
|
} |
|
1645
|
|
|
|
|
|
|
|
|
1646
|
|
|
|
|
|
|
my $ret = $cui->dialog( |
|
1647
|
|
|
|
|
|
|
-title => 'Restarting program', |
|
1648
|
|
|
|
|
|
|
-buttons => [{ |
|
1649
|
|
|
|
|
|
|
-label => '< Save config first >', |
|
1650
|
|
|
|
|
|
|
-value => 1, |
|
1651
|
|
|
|
|
|
|
-shortcut => 's' |
|
1652
|
|
|
|
|
|
|
}, |
|
1653
|
|
|
|
|
|
|
{ -label => '< Restart only >', |
|
1654
|
|
|
|
|
|
|
-value => 2, |
|
1655
|
|
|
|
|
|
|
-shortcut => 'r' |
|
1656
|
|
|
|
|
|
|
}, |
|
1657
|
|
|
|
|
|
|
{ -label => '< Exit - Return >', |
|
1658
|
|
|
|
|
|
|
-value => 0, |
|
1659
|
|
|
|
|
|
|
-shortcut => 'x' |
|
1660
|
|
|
|
|
|
|
}, |
|
1661
|
|
|
|
|
|
|
], |
|
1662
|
|
|
|
|
|
|
-message => 'Choose option to restarting program', |
|
1663
|
|
|
|
|
|
|
window_style(), |
|
1664
|
|
|
|
|
|
|
); |
|
1665
|
|
|
|
|
|
|
if ($ret) { |
|
1666
|
|
|
|
|
|
|
save_state_file($fConfig) if ($ret == 1); |
|
1667
|
|
|
|
|
|
|
$db_exit = 1; |
|
1668
|
|
|
|
|
|
|
DoRestart(); |
|
1669
|
|
|
|
|
|
|
} |
|
1670
|
|
|
|
|
|
|
}, |
|
1671
|
|
|
|
|
|
|
"Restart", |
|
1672
|
|
|
|
|
|
|
"Restart program", |
|
1673
|
|
|
|
|
|
|
"\cR" |
|
1674
|
|
|
|
|
|
|
)); |
|
1675
|
|
|
|
|
|
|
push( |
|
1676
|
|
|
|
|
|
|
@aFile, |
|
1677
|
|
|
|
|
|
|
set_key_binding( |
|
1678
|
|
|
|
|
|
|
sub { |
|
1679
|
|
|
|
|
|
|
my $filename = $cui->filebrowser( |
|
1680
|
|
|
|
|
|
|
-title => "Find and load Perl module from file ", |
|
1681
|
|
|
|
|
|
|
-mask => [['\.p[lm]$', 'Perl modules']], |
|
1682
|
|
|
|
|
|
|
DB::window_style(), |
|
1683
|
|
|
|
|
|
|
); |
|
1684
|
|
|
|
|
|
|
if ($filename) { |
|
1685
|
|
|
|
|
|
|
if (!exists($main::{"_<$filename"})) { |
|
1686
|
|
|
|
|
|
|
|
|
1687
|
|
|
|
|
|
|
# Delete dir from modules in actuall directory |
|
1688
|
|
|
|
|
|
|
my $dir = getcwd(); |
|
1689
|
|
|
|
|
|
|
if ($dir) { |
|
1690
|
|
|
|
|
|
|
$dir .= "/"; |
|
1691
|
|
|
|
|
|
|
$filename =~ s/$dir//; |
|
1692
|
|
|
|
|
|
|
} |
|
1693
|
|
|
|
|
|
|
require $filename; |
|
1694
|
|
|
|
|
|
|
} |
|
1695
|
|
|
|
|
|
|
my $source = $current_source = get_source($filename); |
|
1696
|
|
|
|
|
|
|
$sv->source($source) if $source; |
|
1697
|
|
|
|
|
|
|
$sv->intellidraw; |
|
1698
|
|
|
|
|
|
|
} |
|
1699
|
|
|
|
|
|
|
$sv_win->focus; |
|
1700
|
|
|
|
|
|
|
}, |
|
1701
|
|
|
|
|
|
|
"Filebrowser", |
|
1702
|
|
|
|
|
|
|
"Find and load Perl module via browser", |
|
1703
|
|
|
|
|
|
|
"\cF" |
|
1704
|
|
|
|
|
|
|
)); |
|
1705
|
|
|
|
|
|
|
push( |
|
1706
|
|
|
|
|
|
|
@aFile, |
|
1707
|
|
|
|
|
|
|
set_key_binding( |
|
1708
|
|
|
|
|
|
|
sub { ui_open_file('Compiled Files', \@compiled); }, |
|
1709
|
|
|
|
|
|
|
"FilesCompiled", "Show 'Compiled Files' Dialog", |
|
1710
|
|
|
|
|
|
|
KEY_F(11))); |
|
1711
|
|
|
|
|
|
|
push( |
|
1712
|
|
|
|
|
|
|
@aFile, |
|
1713
|
|
|
|
|
|
|
set_key_binding( |
|
1714
|
|
|
|
|
|
|
sub { ui_open_file('Opened Files', [keys(%sources)]); }, |
|
1715
|
|
|
|
|
|
|
"FilesOpened", "Show 'Opened Files' Dialog", |
|
1716
|
|
|
|
|
|
|
KEY_F(12))); |
|
1717
|
|
|
|
|
|
|
push(@aFile, set_key_binding(\&ui_db_export, "Export", "Export information", "\cY")); |
|
1718
|
|
|
|
|
|
|
push( |
|
1719
|
|
|
|
|
|
|
@aFile, |
|
1720
|
|
|
|
|
|
|
set_key_binding( |
|
1721
|
|
|
|
|
|
|
sub { |
|
1722
|
|
|
|
|
|
|
redrawwin($stdscr); |
|
1723
|
|
|
|
|
|
|
ui_update_watch_list(); |
|
1724
|
|
|
|
|
|
|
refresh_stack_menu(); |
|
1725
|
|
|
|
|
|
|
$cui->draw; |
|
1726
|
|
|
|
|
|
|
}, |
|
1727
|
|
|
|
|
|
|
"Refresh", |
|
1728
|
|
|
|
|
|
|
"Refresh windows", |
|
1729
|
|
|
|
|
|
|
"\cN" |
|
1730
|
|
|
|
|
|
|
)); |
|
1731
|
|
|
|
|
|
|
push(@aFile, set_key_binding(\&ui_db_quit, "Quit", "Quit the debugger", "\cQ", "\cC")); |
|
1732
|
|
|
|
|
|
|
|
|
1733
|
|
|
|
|
|
|
# Submenu - Execution |
|
1734
|
|
|
|
|
|
|
push(@aExecution, set_key_binding(\&db_cont, "Continue", "Run|Continue execution", KEY_F(5))); |
|
1735
|
|
|
|
|
|
|
push(@aExecution, set_key_binding(\&db_step_out, "StepOut", "Step Out", KEY_F(6))); |
|
1736
|
|
|
|
|
|
|
push(@aExecution, set_key_binding(\&db_step_in, "StepIn", "Step In", KEY_F(7))); |
|
1737
|
|
|
|
|
|
|
push(@aExecution, set_key_binding(\&db_step_over, "StepOver", "Step Over", KEY_F(8))); |
|
1738
|
|
|
|
|
|
|
push( |
|
1739
|
|
|
|
|
|
|
@aExecution, |
|
1740
|
|
|
|
|
|
|
set_key_binding( |
|
1741
|
|
|
|
|
|
|
sub { |
|
1742
|
|
|
|
|
|
|
if ($ui_window_focused == 2) { |
|
1743
|
|
|
|
|
|
|
db_edit_watch_expr($watch_list); |
|
1744
|
|
|
|
|
|
|
} else { |
|
1745
|
|
|
|
|
|
|
ui_text_editor(1); |
|
1746
|
|
|
|
|
|
|
} |
|
1747
|
|
|
|
|
|
|
}, |
|
1748
|
|
|
|
|
|
|
"ArgumentsEdit", |
|
1749
|
|
|
|
|
|
|
"Edit program paramaters or watched variable", |
|
1750
|
|
|
|
|
|
|
"\cE" |
|
1751
|
|
|
|
|
|
|
)); |
|
1752
|
|
|
|
|
|
|
push(@aExecution, set_key_binding(sub { ui_text_editor(2); }, "EnviromentsEdit", "Edit enviroment paramaters", "\cM")); |
|
1753
|
|
|
|
|
|
|
push( |
|
1754
|
|
|
|
|
|
|
@aExecution, |
|
1755
|
|
|
|
|
|
|
set_key_binding( |
|
1756
|
|
|
|
|
|
|
sub { |
|
1757
|
|
|
|
|
|
|
my $ret = $cui->question( |
|
1758
|
|
|
|
|
|
|
-title => 'Command Execution', |
|
1759
|
|
|
|
|
|
|
-question => 'Please enter an command to enter', |
|
1760
|
|
|
|
|
|
|
DB::window_style(), |
|
1761
|
|
|
|
|
|
|
); |
|
1762
|
|
|
|
|
|
|
$usercontext = $ret if ($ret); |
|
1763
|
|
|
|
|
|
|
}, |
|
1764
|
|
|
|
|
|
|
"RunCommand", |
|
1765
|
|
|
|
|
|
|
"Run perl command", |
|
1766
|
|
|
|
|
|
|
"\cP" |
|
1767
|
|
|
|
|
|
|
)); |
|
1768
|
|
|
|
|
|
|
|
|
1769
|
|
|
|
|
|
|
# Submenu - Breakpoint |
|
1770
|
|
|
|
|
|
|
push(@aBreakpoint, |
|
1771
|
|
|
|
|
|
|
set_key_binding(sub { set_active_window(1); db_toggle_break(0, undef) }, "Breakpoint", "Toggle Breakpoint", KEY_F(9))); |
|
1772
|
|
|
|
|
|
|
push( |
|
1773
|
|
|
|
|
|
|
@aBreakpoint, |
|
1774
|
|
|
|
|
|
|
set_key_binding( |
|
1775
|
|
|
|
|
|
|
sub { set_active_window(1); db_toggle_break(1, undef) }, |
|
1776
|
|
|
|
|
|
|
"BreakpointCode", "Toggle Breakpoint Code", "\cO" |
|
1777
|
|
|
|
|
|
|
)); |
|
1778
|
|
|
|
|
|
|
push(@aBreakpoint, set_key_binding(sub { db_add_watch_expr(undef) }, "WatchExpression", "Add watch expression", "\cW")); |
|
1779
|
|
|
|
|
|
|
push(@aBreakpoint, set_key_binding(\&ui_list_breakpoints, "ListBreakpoints", "List all breakpoints", "\cB")); |
|
1780
|
|
|
|
|
|
|
push(@aBreakpoint, set_key_binding(\&clearalldblines, "ClearBreakpoints", "Clear all breakpoints")); |
|
1781
|
|
|
|
|
|
|
push(@aBreakpoint, |
|
1782
|
|
|
|
|
|
|
set_key_binding(sub { @watch_exprs = (); $update_watch_list = 1; }, "ClearWatches", "Clear all watches")); |
|
1783
|
|
|
|
|
|
|
push( |
|
1784
|
|
|
|
|
|
|
@aBreakpoint, |
|
1785
|
|
|
|
|
|
|
set_key_binding( |
|
1786
|
|
|
|
|
|
|
sub { &clearalldblines(); @watch_exprs = (); $update_watch_list = 1; }, |
|
1787
|
|
|
|
|
|
|
"ClearAll", "Clear all settings", "\cX" |
|
1788
|
|
|
|
|
|
|
)); |
|
1789
|
|
|
|
|
|
|
|
|
1790
|
|
|
|
|
|
|
# Submenu - Settings |
|
1791
|
|
|
|
|
|
|
push( |
|
1792
|
|
|
|
|
|
|
@aSettings, |
|
1793
|
|
|
|
|
|
|
set_key_binding( |
|
1794
|
|
|
|
|
|
|
sub { |
|
1795
|
|
|
|
|
|
|
my $ret = $cui->dialog( |
|
1796
|
|
|
|
|
|
|
-title => 'Load saved config files', |
|
1797
|
|
|
|
|
|
|
-buttons => [{ |
|
1798
|
|
|
|
|
|
|
-label => '< User conf >', |
|
1799
|
|
|
|
|
|
|
-value => 1, |
|
1800
|
|
|
|
|
|
|
-shortcut => 'u' |
|
1801
|
|
|
|
|
|
|
}, |
|
1802
|
|
|
|
|
|
|
{ -label => '< Default conf >', |
|
1803
|
|
|
|
|
|
|
-value => 2, |
|
1804
|
|
|
|
|
|
|
-shortcut => 'd' |
|
1805
|
|
|
|
|
|
|
}, |
|
1806
|
|
|
|
|
|
|
{ -label => '< Exit >', |
|
1807
|
|
|
|
|
|
|
-value => 0, |
|
1808
|
|
|
|
|
|
|
-shortcut => 'x' |
|
1809
|
|
|
|
|
|
|
}, |
|
1810
|
|
|
|
|
|
|
], |
|
1811
|
|
|
|
|
|
|
-message => 'Do you really want load config?', |
|
1812
|
|
|
|
|
|
|
window_style(), |
|
1813
|
|
|
|
|
|
|
); |
|
1814
|
|
|
|
|
|
|
if ($ret) { |
|
1815
|
|
|
|
|
|
|
load_state_file($fConfig, ($ret == 2 ? ".rc" : "")); |
|
1816
|
|
|
|
|
|
|
$user_conf_readed = $ret == 1 ? 1 : 0; |
|
1817
|
|
|
|
|
|
|
} |
|
1818
|
|
|
|
|
|
|
}, |
|
1819
|
|
|
|
|
|
|
"ConfigLoad", |
|
1820
|
|
|
|
|
|
|
"Load config file", |
|
1821
|
|
|
|
|
|
|
"\cL" |
|
1822
|
|
|
|
|
|
|
)); |
|
1823
|
|
|
|
|
|
|
push( |
|
1824
|
|
|
|
|
|
|
@aSettings, |
|
1825
|
|
|
|
|
|
|
set_key_binding( |
|
1826
|
|
|
|
|
|
|
sub { |
|
1827
|
|
|
|
|
|
|
save_state_file($fConfig) |
|
1828
|
|
|
|
|
|
|
if $cui->dialog( |
|
1829
|
|
|
|
|
|
|
-title => 'Save config file', |
|
1830
|
|
|
|
|
|
|
-buttons => ['yes', 'no'], |
|
1831
|
|
|
|
|
|
|
-message => 'Do you really want save config?', |
|
1832
|
|
|
|
|
|
|
window_style(), |
|
1833
|
|
|
|
|
|
|
); |
|
1834
|
|
|
|
|
|
|
}, |
|
1835
|
|
|
|
|
|
|
"ConfigSave", |
|
1836
|
|
|
|
|
|
|
"Save config file", |
|
1837
|
|
|
|
|
|
|
"\cS" |
|
1838
|
|
|
|
|
|
|
)); |
|
1839
|
|
|
|
|
|
|
|
|
1840
|
|
|
|
|
|
|
# Submenu - View |
|
1841
|
|
|
|
|
|
|
push( |
|
1842
|
|
|
|
|
|
|
@aView, |
|
1843
|
|
|
|
|
|
|
set_key_binding( |
|
1844
|
|
|
|
|
|
|
sub { |
|
1845
|
|
|
|
|
|
|
my $text; |
|
1846
|
|
|
|
|
|
|
local $Data::Dumper::Purity = 0; |
|
1847
|
|
|
|
|
|
|
local $Data::Dumper::Terse = 1; |
|
1848
|
|
|
|
|
|
|
local $Data::Dumper::Indent = 2; |
|
1849
|
|
|
|
|
|
|
local $Data::Dumper::Sortkeys = 1; |
|
1850
|
|
|
|
|
|
|
$text = (scalar(@Devel::PDB::script_args) ? Dumper(@Devel::PDB::script_args) : "Not arguments putted"); |
|
1851
|
|
|
|
|
|
|
dialog_message( |
|
1852
|
|
|
|
|
|
|
-title => "Arguments", |
|
1853
|
|
|
|
|
|
|
-message => $text |
|
1854
|
|
|
|
|
|
|
); |
|
1855
|
|
|
|
|
|
|
|
|
1856
|
|
|
|
|
|
|
}, |
|
1857
|
|
|
|
|
|
|
"Arguments", |
|
1858
|
|
|
|
|
|
|
"View program parameters", |
|
1859
|
|
|
|
|
|
|
"\cA" |
|
1860
|
|
|
|
|
|
|
)); |
|
1861
|
|
|
|
|
|
|
push(@aView, set_key_binding(sub { set_active_window(1) }, "WindowSource", "Switch to the Source Code Window", KEY_F(1))); |
|
1862
|
|
|
|
|
|
|
push(@aView, |
|
1863
|
|
|
|
|
|
|
set_key_binding(sub { set_active_window(2) }, "WindowLexical", "Switch to the Lexical Variable Window", KEY_F(2))); |
|
1864
|
|
|
|
|
|
|
push(@aView, set_key_binding(sub { set_active_window(3) }, "WindowWatches", "Switch to the Watch Window", KEY_F(3))); |
|
1865
|
|
|
|
|
|
|
push(@aView, set_key_binding(sub { ui_view_stack(0) }, "WindowStack", "View Stack Window", "\cT")); |
|
1866
|
|
|
|
|
|
|
push(@aView, set_key_binding(sub { ui_text_editor(3) }, "ViewVariables", "View special variables", "\cU")); |
|
1867
|
|
|
|
|
|
|
|
|
1868
|
|
|
|
|
|
|
push(@aView, |
|
1869
|
|
|
|
|
|
|
set_key_binding(sub { ui_adjust_vert_parts(1) }, "VerticalPartsMin", "Vertical window(Source file) minimize", '{')); |
|
1870
|
|
|
|
|
|
|
push(@aView, |
|
1871
|
|
|
|
|
|
|
set_key_binding(sub { ui_adjust_vert_parts(-1) }, "VerticalPartsMax", "Vertical window(Source file) maximize", '}')); |
|
1872
|
|
|
|
|
|
|
push(@aView, |
|
1873
|
|
|
|
|
|
|
set_key_binding(sub { ui_adjust_hori_parts(-1) }, "HorizontalPartsMin", "Horizontal window(Stack) minimize", '[')); |
|
1874
|
|
|
|
|
|
|
push(@aView, |
|
1875
|
|
|
|
|
|
|
set_key_binding(sub { ui_adjust_hori_parts(1) }, "HorizontalPartsMin", "Horizontal window(Stack) maximize", ']')); |
|
1876
|
|
|
|
|
|
|
|
|
1877
|
|
|
|
|
|
|
$cui->add( |
|
1878
|
|
|
|
|
|
|
'menu', |
|
1879
|
|
|
|
|
|
|
'Menubar', |
|
1880
|
|
|
|
|
|
|
-menu => [{ |
|
1881
|
|
|
|
|
|
|
-label => 'File', |
|
1882
|
|
|
|
|
|
|
-submenu => \@aFile, |
|
1883
|
|
|
|
|
|
|
}, |
|
1884
|
|
|
|
|
|
|
{ -label => 'View', |
|
1885
|
|
|
|
|
|
|
-submenu => \@aView, |
|
1886
|
|
|
|
|
|
|
}, |
|
1887
|
|
|
|
|
|
|
{ -label => 'Execution', |
|
1888
|
|
|
|
|
|
|
-submenu => \@aExecution, |
|
1889
|
|
|
|
|
|
|
}, |
|
1890
|
|
|
|
|
|
|
{ -label => 'Breakpoint', |
|
1891
|
|
|
|
|
|
|
-submenu => \@aBreakpoint, |
|
1892
|
|
|
|
|
|
|
}, |
|
1893
|
|
|
|
|
|
|
{ -label => 'Settings', |
|
1894
|
|
|
|
|
|
|
-submenu => \@aSettings, |
|
1895
|
|
|
|
|
|
|
}, |
|
1896
|
|
|
|
|
|
|
{ -label => 'Help', |
|
1897
|
|
|
|
|
|
|
-submenu => [{ |
|
1898
|
|
|
|
|
|
|
-label => 'Keys', |
|
1899
|
|
|
|
|
|
|
-value => \&ui_db_help, |
|
1900
|
|
|
|
|
|
|
}, |
|
1901
|
|
|
|
|
|
|
{ -label => 'About', |
|
1902
|
|
|
|
|
|
|
-value => sub { |
|
1903
|
|
|
|
|
|
|
dialog_message( |
|
1904
|
|
|
|
|
|
|
-title => "About", |
|
1905
|
|
|
|
|
|
|
-message => <
|
|
1906
|
|
|
|
|
|
|
Devel::PDB - A simple Curses-based Perl DeBugger in version $VERSION |
|
1907
|
|
|
|
|
|
|
|
|
1908
|
|
|
|
|
|
|
PerlDeBugger is a Curses-based Perl debugger with most of the essential functions such as monitoring windows for paddlist, |
|
1909
|
|
|
|
|
|
|
call stack, custom watch expressions, etc. |
|
1910
|
|
|
|
|
|
|
Suitable for debugging or tracing complicated Perl applications on the spot. |
|
1911
|
|
|
|
|
|
|
|
|
1912
|
|
|
|
|
|
|
AUTHORS |
|
1913
|
|
|
|
|
|
|
Ivan Yat-Cheung Wong |
|
1914
|
|
|
|
|
|
|
Igor Bujna |
|
1915
|
|
|
|
|
|
|
|
|
1916
|
|
|
|
|
|
|
MODULES |
|
1917
|
|
|
|
|
|
|
Curses - $Curses::VERSION |
|
1918
|
|
|
|
|
|
|
Curses:UI - $Curses::UI::VERSION |
|
1919
|
|
|
|
|
|
|
|
|
1920
|
|
|
|
|
|
|
EOF |
|
1921
|
|
|
|
|
|
|
, |
|
1922
|
|
|
|
|
|
|
DB::window_style(), |
|
1923
|
|
|
|
|
|
|
); |
|
1924
|
|
|
|
|
|
|
}, |
|
1925
|
|
|
|
|
|
|
}, |
|
1926
|
|
|
|
|
|
|
] |
|
1927
|
|
|
|
|
|
|
}, |
|
1928
|
|
|
|
|
|
|
], |
|
1929
|
|
|
|
|
|
|
window_style(), |
|
1930
|
|
|
|
|
|
|
); |
|
1931
|
|
|
|
|
|
|
|
|
1932
|
|
|
|
|
|
|
#open my $fd0, '>stdout'; |
|
1933
|
|
|
|
|
|
|
#open my $fd1, '>stderr'; |
|
1934
|
|
|
|
|
|
|
#open STDOUT, ">&$fd0"; |
|
1935
|
|
|
|
|
|
|
#open STDERR, ">&$fd1"; |
|
1936
|
|
|
|
|
|
|
#open STDOUT, ">stdout"; |
|
1937
|
|
|
|
|
|
|
|
|
1938
|
|
|
|
|
|
|
unlink config_file($_) foreach ('stderr', 'stdout'); |
|
1939
|
|
|
|
|
|
|
open STDERR, ">>" . config_file("stderr"); |
|
1940
|
|
|
|
|
|
|
open $output, ">>" . config_file("stdout"); |
|
1941
|
|
|
|
|
|
|
open $stdout, ">>&STDOUT"; |
|
1942
|
|
|
|
|
|
|
|
|
1943
|
|
|
|
|
|
|
select(STDERR); |
|
1944
|
|
|
|
|
|
|
$| = 1; |
|
1945
|
|
|
|
|
|
|
select(STDOUT); |
|
1946
|
|
|
|
|
|
|
$| = 1; |
|
1947
|
|
|
|
|
|
|
|
|
1948
|
|
|
|
|
|
|
$inited = 1; |
|
1949
|
|
|
|
|
|
|
|
|
1950
|
|
|
|
|
|
|
# Load actual breakpoints and watches |
|
1951
|
|
|
|
|
|
|
load_state_file(config_file("conf.rc")); |
|
1952
|
|
|
|
|
|
|
} |
|
1953
|
|
|
|
|
|
|
|
|
1954
|
|
|
|
|
|
|
# |
|
1955
|
|
|
|
|
|
|
# Return for given filename which find or creater for given param |
|
1956
|
|
|
|
|
|
|
# |
|
1957
|
|
|
|
|
|
|
sub get_source { |
|
1958
|
|
|
|
|
|
|
my $filename = shift; |
|
1959
|
|
|
|
|
|
|
my $source = $sources{$filename}; |
|
1960
|
|
|
|
|
|
|
|
|
1961
|
|
|
|
|
|
|
if (!defined $source) { |
|
1962
|
|
|
|
|
|
|
local (*dbline) = $main::{"_<$filename"}; |
|
1963
|
|
|
|
|
|
|
$sources{$filename} = $source = new Devel::PDB::Source( |
|
1964
|
|
|
|
|
|
|
filename => $filename, |
|
1965
|
|
|
|
|
|
|
lines => \@dbline, |
|
1966
|
|
|
|
|
|
|
breaks => \%dbline, |
|
1967
|
|
|
|
|
|
|
); |
|
1968
|
|
|
|
|
|
|
} |
|
1969
|
|
|
|
|
|
|
|
|
1970
|
|
|
|
|
|
|
return $source; |
|
1971
|
|
|
|
|
|
|
} |
|
1972
|
|
|
|
|
|
|
|
|
1973
|
|
|
|
|
|
|
# |
|
1974
|
|
|
|
|
|
|
# Updating watch list in Watches window |
|
1975
|
|
|
|
|
|
|
# |
|
1976
|
|
|
|
|
|
|
sub ui_update_watch_list { |
|
1977
|
|
|
|
|
|
|
local $Data::Dumper::Terse = 1; |
|
1978
|
|
|
|
|
|
|
local $Data::Dumper::Maxdepth; |
|
1979
|
|
|
|
|
|
|
local $Data::Dumper::Indent; |
|
1980
|
|
|
|
|
|
|
local $Data::Dumper::Sortkeys = 1; |
|
1981
|
|
|
|
|
|
|
|
|
1982
|
|
|
|
|
|
|
foreach my $expr (@watch_exprs) { |
|
1983
|
|
|
|
|
|
|
$evalarg = $expr->{name}; |
|
1984
|
|
|
|
|
|
|
my $res = &DB::eval; |
|
1985
|
|
|
|
|
|
|
$Data::Dumper::Indent = 0; |
|
1986
|
|
|
|
|
|
|
$Data::Dumper::Maxdepth = 2; |
|
1987
|
|
|
|
|
|
|
$expr->{value} = Dumper $res; |
|
1988
|
|
|
|
|
|
|
$Data::Dumper::Indent = 1; |
|
1989
|
|
|
|
|
|
|
$Data::Dumper::Maxdepth = 0; |
|
1990
|
|
|
|
|
|
|
$expr->{long_value} = Dumper $res; |
|
1991
|
|
|
|
|
|
|
} |
|
1992
|
|
|
|
|
|
|
|
|
1993
|
|
|
|
|
|
|
$watch_list->update; |
|
1994
|
|
|
|
|
|
|
} |
|
1995
|
|
|
|
|
|
|
|
|
1996
|
|
|
|
|
|
|
# |
|
1997
|
|
|
|
|
|
|
# Perl Debugger methods |
|
1998
|
|
|
|
|
|
|
# |
|
1999
|
|
|
|
|
|
|
my @saved; |
|
2000
|
|
|
|
|
|
|
|
|
2001
|
|
|
|
|
|
|
sub save { |
|
2002
|
|
|
|
|
|
|
@saved = ($@, $!, $,, $/, $\, $^W); |
|
2003
|
|
|
|
|
|
|
$, = ''; |
|
2004
|
|
|
|
|
|
|
$/ = "\n"; |
|
2005
|
|
|
|
|
|
|
$\ = ''; |
|
2006
|
|
|
|
|
|
|
$^W = 0; |
|
2007
|
|
|
|
|
|
|
} |
|
2008
|
|
|
|
|
|
|
|
|
2009
|
|
|
|
|
|
|
sub eval { |
|
2010
|
|
|
|
|
|
|
($@, $!, $,, $/, $\, $^W) = @saved; |
|
2011
|
|
|
|
|
|
|
my $res = eval "package $package; $evalarg"; |
|
2012
|
|
|
|
|
|
|
|
|
2013
|
|
|
|
|
|
|
#my $res = eval 'no strict;($@, $!, $^E, $,, $/, $\, $^W) = @saved;' . "package $package;$evalarg ;"; |
|
2014
|
|
|
|
|
|
|
|
|
2015
|
|
|
|
|
|
|
save; |
|
2016
|
|
|
|
|
|
|
$res; |
|
2017
|
|
|
|
|
|
|
} |
|
2018
|
|
|
|
|
|
|
|
|
2019
|
|
|
|
|
|
|
# Main method which is load when program started, stopped or step in position where is breakpoint |
|
2020
|
|
|
|
|
|
|
sub DB { |
|
2021
|
|
|
|
|
|
|
return if $exit; |
|
2022
|
|
|
|
|
|
|
save; |
|
2023
|
|
|
|
|
|
|
init if !$inited; |
|
2024
|
|
|
|
|
|
|
|
|
2025
|
|
|
|
|
|
|
RESTART: |
|
2026
|
|
|
|
|
|
|
open STDOUT, ">>&", $stdout; |
|
2027
|
|
|
|
|
|
|
|
|
2028
|
|
|
|
|
|
|
($package, $filename, $line) = caller; |
|
2029
|
|
|
|
|
|
|
|
|
2030
|
|
|
|
|
|
|
my $scope = $current_sub ? $current_sub : $package; |
|
2031
|
|
|
|
|
|
|
my $renew = !defined $padlist_scope || $scope ne $padlist_scope; |
|
2032
|
|
|
|
|
|
|
if ($renew) { |
|
2033
|
|
|
|
|
|
|
%padlist = (); |
|
2034
|
|
|
|
|
|
|
@padlist_disp = (); |
|
2035
|
|
|
|
|
|
|
$padlist_scope = $scope; |
|
2036
|
|
|
|
|
|
|
} |
|
2037
|
|
|
|
|
|
|
|
|
2038
|
|
|
|
|
|
|
# BUGS: |
|
2039
|
|
|
|
|
|
|
# compadlist not return, not defined variables. |
|
2040
|
|
|
|
|
|
|
# Variables must be defined via (my,our,....etc) or 'use strict;' on yours script |
|
2041
|
|
|
|
|
|
|
{ |
|
2042
|
|
|
|
|
|
|
my ($names, $vals) = |
|
2043
|
|
|
|
|
|
|
$scope eq 'main' |
|
2044
|
|
|
|
|
|
|
? comppadlist->ARRAY |
|
2045
|
|
|
|
|
|
|
: svref_2object(\&$scope)->PADLIST->ARRAY; |
|
2046
|
|
|
|
|
|
|
my @names = $names->ARRAY; |
|
2047
|
|
|
|
|
|
|
my @vals = $vals->ARRAY; |
|
2048
|
|
|
|
|
|
|
my $count = @names; |
|
2049
|
|
|
|
|
|
|
|
|
2050
|
|
|
|
|
|
|
refresh_stack_menu(); |
|
2051
|
|
|
|
|
|
|
|
|
2052
|
|
|
|
|
|
|
local $Data::Dumper::Terse = 1; |
|
2053
|
|
|
|
|
|
|
local $Data::Dumper::Maxdepth; |
|
2054
|
|
|
|
|
|
|
local $Data::Dumper::Indent; |
|
2055
|
|
|
|
|
|
|
local $Data::Dumper::Sortkeys = 1; |
|
2056
|
|
|
|
|
|
|
|
|
2057
|
|
|
|
|
|
|
my %h_pd = map { $_->{name} => $_ } @padlist_disp; |
|
2058
|
|
|
|
|
|
|
|
|
2059
|
|
|
|
|
|
|
for (my ($i, $j) = (0, 0); $i < $count; $i++) { |
|
2060
|
|
|
|
|
|
|
my $sv = $names[$i]; |
|
2061
|
|
|
|
|
|
|
next if class($sv) eq 'SPECIAL'; |
|
2062
|
|
|
|
|
|
|
my $name = $sv->PVX; |
|
2063
|
|
|
|
|
|
|
$Data::Dumper::Indent = 0; |
|
2064
|
|
|
|
|
|
|
$Data::Dumper::Maxdepth = 2; |
|
2065
|
|
|
|
|
|
|
my $val = Dumper $vals[$i]->object_2svref; |
|
2066
|
|
|
|
|
|
|
$val =~ s/^\\// if class($sv) ne 'RV'; |
|
2067
|
|
|
|
|
|
|
$Data::Dumper::Indent = 1; |
|
2068
|
|
|
|
|
|
|
$Data::Dumper::Maxdepth = 0; |
|
2069
|
|
|
|
|
|
|
my $long_val = Dumper $vals[$i]->object_2svref; |
|
2070
|
|
|
|
|
|
|
$long_val =~ s/^\\// if class($sv) ne 'RV'; |
|
2071
|
|
|
|
|
|
|
|
|
2072
|
|
|
|
|
|
|
if ($renew || $val ne $padlist{$name}) { |
|
2073
|
|
|
|
|
|
|
my $rh = {name => $name, value => $val, long_value => $long_val}; |
|
2074
|
|
|
|
|
|
|
$padlist_disp[$j] = $rh; |
|
2075
|
|
|
|
|
|
|
$padlist{$name} = $val; |
|
2076
|
|
|
|
|
|
|
$h_pd{$name} = $rh; |
|
2077
|
|
|
|
|
|
|
} |
|
2078
|
|
|
|
|
|
|
++$j; |
|
2079
|
|
|
|
|
|
|
} |
|
2080
|
|
|
|
|
|
|
|
|
2081
|
|
|
|
|
|
|
# Sorting values in stack by name |
|
2082
|
|
|
|
|
|
|
@padlist_disp = (); |
|
2083
|
|
|
|
|
|
|
@padlist_disp = sort { $a->{name} cmp $b->{name} } values %h_pd; |
|
2084
|
|
|
|
|
|
|
|
|
2085
|
|
|
|
|
|
|
$padvar_list->update($renew); |
|
2086
|
|
|
|
|
|
|
} |
|
2087
|
|
|
|
|
|
|
|
|
2088
|
|
|
|
|
|
|
#local (*dbline) = $main::{"_<$filename"}; |
|
2089
|
|
|
|
|
|
|
$sv->source($current_source = get_source($filename)); |
|
2090
|
|
|
|
|
|
|
$current_source->current_line($line); |
|
2091
|
|
|
|
|
|
|
|
|
2092
|
|
|
|
|
|
|
ui_update_watch_list; |
|
2093
|
|
|
|
|
|
|
|
|
2094
|
|
|
|
|
|
|
$yield = 0; |
|
2095
|
|
|
|
|
|
|
|
|
2096
|
|
|
|
|
|
|
# Breakpoint with action |
|
2097
|
|
|
|
|
|
|
my $brkp = $current_source->ret_line_breakpoint(); |
|
2098
|
|
|
|
|
|
|
my ($stop, $action) = $brkp ? split(/\0/, $brkp) : (); |
|
2099
|
|
|
|
|
|
|
if ($action) { |
|
2100
|
|
|
|
|
|
|
my $res = eval "return 1 if ($action); return 0;\n"; |
|
2101
|
|
|
|
|
|
|
if ($@) { |
|
2102
|
|
|
|
|
|
|
my $str = $@; |
|
2103
|
|
|
|
|
|
|
db_toggle_break(1, \$str); |
|
2104
|
|
|
|
|
|
|
} |
|
2105
|
|
|
|
|
|
|
$yield = 1 unless ($res); |
|
2106
|
|
|
|
|
|
|
} |
|
2107
|
|
|
|
|
|
|
|
|
2108
|
|
|
|
|
|
|
$new_single = $single; |
|
2109
|
|
|
|
|
|
|
$cui->focus(undef, 1); |
|
2110
|
|
|
|
|
|
|
$cui->draw; |
|
2111
|
|
|
|
|
|
|
$update_watch_list = 0; |
|
2112
|
|
|
|
|
|
|
while (!$yield) { |
|
2113
|
|
|
|
|
|
|
|
|
2114
|
|
|
|
|
|
|
# Wait for any key |
|
2115
|
|
|
|
|
|
|
$cui->do_one_event; |
|
2116
|
|
|
|
|
|
|
if ($update_watch_list) { |
|
2117
|
|
|
|
|
|
|
ui_update_watch_list; |
|
2118
|
|
|
|
|
|
|
$cui->draw; |
|
2119
|
|
|
|
|
|
|
} |
|
2120
|
|
|
|
|
|
|
|
|
2121
|
|
|
|
|
|
|
if ($usercontext) { # User eval |
|
2122
|
|
|
|
|
|
|
#my $usc = 'no strict;($@, $!, $^E, $,, $/, $\, $^W) = @saved;' . "package $package;"; |
|
2123
|
|
|
|
|
|
|
#my $arg = "\$^D = \$^D | \$DB::db_stop;\n$usercontext"; |
|
2124
|
|
|
|
|
|
|
#eval "$usc $arg;\n"; |
|
2125
|
|
|
|
|
|
|
eval "$usercontext;\n"; |
|
2126
|
|
|
|
|
|
|
print_error($@) if ($@); |
|
2127
|
|
|
|
|
|
|
$usercontext = undef; |
|
2128
|
|
|
|
|
|
|
goto RESTART; |
|
2129
|
|
|
|
|
|
|
} |
|
2130
|
|
|
|
|
|
|
} |
|
2131
|
|
|
|
|
|
|
$single = $new_single; |
|
2132
|
|
|
|
|
|
|
|
|
2133
|
|
|
|
|
|
|
open STDOUT, ">>&", $output; |
|
2134
|
|
|
|
|
|
|
($@, $!, $,, $/, $\, $^W) = @saved; |
|
2135
|
|
|
|
|
|
|
} |
|
2136
|
|
|
|
|
|
|
|
|
2137
|
|
|
|
|
|
|
sub sub { |
|
2138
|
|
|
|
|
|
|
my ($ret, @ret); |
|
2139
|
|
|
|
|
|
|
|
|
2140
|
|
|
|
|
|
|
local $current_sub = $sub; |
|
2141
|
|
|
|
|
|
|
local $stack_depth = $stack_depth + 1; |
|
2142
|
|
|
|
|
|
|
$#stack = $stack_depth; |
|
2143
|
|
|
|
|
|
|
$stack[-1] = $single; |
|
2144
|
|
|
|
|
|
|
$single &= 1; |
|
2145
|
|
|
|
|
|
|
|
|
2146
|
|
|
|
|
|
|
if (wantarray) { |
|
2147
|
|
|
|
|
|
|
no strict; |
|
2148
|
|
|
|
|
|
|
@ret = &$sub; |
|
2149
|
|
|
|
|
|
|
use strict; |
|
2150
|
|
|
|
|
|
|
$single |= $stack[$stack_depth--]; |
|
2151
|
|
|
|
|
|
|
@ret; |
|
2152
|
|
|
|
|
|
|
} else { |
|
2153
|
|
|
|
|
|
|
if (defined wantarray) { |
|
2154
|
|
|
|
|
|
|
no strict; |
|
2155
|
|
|
|
|
|
|
$ret = &$sub; |
|
2156
|
|
|
|
|
|
|
use strict; |
|
2157
|
|
|
|
|
|
|
} else { |
|
2158
|
|
|
|
|
|
|
no strict; |
|
2159
|
|
|
|
|
|
|
&$sub; |
|
2160
|
|
|
|
|
|
|
use strict; |
|
2161
|
|
|
|
|
|
|
undef $ret; |
|
2162
|
|
|
|
|
|
|
} |
|
2163
|
|
|
|
|
|
|
|
|
2164
|
|
|
|
|
|
|
$single |= $stack[$stack_depth--]; |
|
2165
|
|
|
|
|
|
|
$ret; |
|
2166
|
|
|
|
|
|
|
} |
|
2167
|
|
|
|
|
|
|
} |
|
2168
|
|
|
|
|
|
|
|
|
2169
|
|
|
|
|
|
|
sub postponed { |
|
2170
|
|
|
|
|
|
|
my $file = shift; |
|
2171
|
|
|
|
|
|
|
push @compiled, $$file; |
|
2172
|
|
|
|
|
|
|
|
|
2173
|
|
|
|
|
|
|
my $key = "_<" . $$file; |
|
2174
|
|
|
|
|
|
|
return if (!exists($postponed_file{$key})); |
|
2175
|
|
|
|
|
|
|
|
|
2176
|
|
|
|
|
|
|
set_breakpoints($key, $postponed_file{$key}); |
|
2177
|
|
|
|
|
|
|
delete($postponed_file{$key}); |
|
2178
|
|
|
|
|
|
|
|
|
2179
|
|
|
|
|
|
|
} |
|
2180
|
|
|
|
|
|
|
|
|
2181
|
|
|
|
|
|
|
package Devel::PDB; |
|
2182
|
|
|
|
|
|
|
|
|
2183
|
|
|
|
|
|
|
1; |
|
2184
|
|
|
|
|
|
|
|
|
2185
|
|
|
|
|
|
|
__END__ |