File Coverage

blib/lib/Devel/Command/DBSub/DB_5_6.pm
Criterion Covered Total %
statement 8 726 1.1
branch 1 498 0.2
condition 0 101 0.0
subroutine 3 4 75.0
pod 0 1 0.0
total 12 1330 0.9


line stmt bran cond sub pod time code
1             package Devel::Command::DBSub::DB_5_6;
2              
3             sub import {
4 1 50   1   6 if ($] =~ /^5.006/) {
5             # This module will work.
6 0         0 return \&DB::alt_56_DB;
7             }
8             else {
9             # Not a 5.6 Perl.
10 1         4 return undef;
11             }
12             }
13              
14             # The patched 5.6 debugger's DB() routine.
15             {
16 1     1   2412 no strict;
  1         2  
  1         29  
17 1     1   5 no warnings;
  1         2  
  1         12076  
18             package DB;
19              
20             sub alt_56_DB {
21             # _After_ the perl program is compiled, $single is set to 1:
22 0 0 0 0 0   if ($single and not $second_time++) {
23 0 0         if ($runnonstop) { # Disable until signal
    0          
24 0           for ($i=0; $i <= $stack_depth; ) {
25 0           $stack[$i++] &= ~1;
26             }
27 0           $single = 0;
28             # return; # Would not print trace!
29             } elsif ($ImmediateStop) {
30 0           $ImmediateStop = 0;
31 0           $signal = 1;
32             }
33             }
34 0 0 0       $runnonstop = 0 if $single or $signal; # Disable it if interactive.
35 0           &save;
36 0           ($package, $filename, $line) = caller;
37 0           $filename_ini = $filename;
38 0           $usercontext = '($@, $!, $^E, $,, $/, $\, $^W) = @saved;' .
39             "package $package;"; # this won't let them modify, alas
40 0           local(*dbline) = $main::{'_<' . $filename};
41 0           $max = $#dbline;
42 0 0         if (($stop,$action) = split(/\0/,$dbline{$line})) {
43 0 0         if ($stop eq '1') {
    0          
44 0           $signal |= 1;
45             } elsif ($stop) {
46 0           $evalarg = "\$DB::signal |= 1 if do {$stop}"; &eval;
  0            
47 0           $dbline{$line} =~ s/;9($|\0)/$1/;
48             }
49             }
50 0           my $was_signal = $signal;
51 0 0         if ($trace & 2) {
52 0           for (my $n = 0; $n <= $#to_watch; $n++) {
53 0           $evalarg = $to_watch[$n];
54 0           local $onetimeDump; # Do not output results
55 0           my ($val) = &eval; # Fix context (&eval is doing array)?
56 0 0         $val = ( (defined $val) ? "'$val'" : 'undef' );
57 0 0         if ($val ne $old_watch[$n]) {
58 0           $signal = 1;
59 0           print $OUT <
60             Watchpoint $n:\t$to_watch[$n] changed:
61             old value:\t$old_watch[$n]
62             new value:\t$val
63             EOP
64 0           $old_watch[$n] = $val;
65             }
66             }
67             }
68 0 0         if ($trace & 4) { # User-installed watch
69 0 0 0       return if watchfunction($package, $filename, $line)
      0        
      0        
70             and not $single and not $was_signal and not ($trace & ~4);
71             }
72 0           $was_signal = $signal;
73 0           $signal = 0;
74 0 0 0       if ($single || ($trace & 1) || $was_signal) {
      0        
75 0 0         if ($slave_editor) {
    0          
76 0           $position = "\032\032$filename:$line:0\n";
77 0           print $LINEINFO $position;
78             } elsif ($package eq 'DB::fake') {
79 0 0         $term || &setterm;
80 0           print_help(<
81             Debugged program terminated. Use B to quit or B to restart,
82             use B I to avoid stopping after program termination,
83             B, B or B to get additional info.
84             EOP
85 0           $package = 'main';
86 0           $usercontext = '($@, $!, $^E, $,, $/, $\, $^W) = @saved;' .
87             "package $package;"; # this won't let them modify, alas
88             } else {
89 0           $sub =~ s/\'/::/;
90 0 0         $prefix = $sub =~ /::/ ? "" : "${'package'}::";
  0            
91 0           $prefix .= "$sub($filename:";
92 0 0         $after = ($dbline[$line] =~ /\n$/ ? '' : "\n");
93 0 0         if (length($prefix) > 30) {
94 0           $position = "$prefix$line):\n$line:\t$dbline[$line]$after";
95 0           $prefix = "";
96 0           $infix = ":\t";
97             } else {
98 0           $infix = "):\t";
99 0           $position = "$prefix$line$infix$dbline[$line]$after";
100             }
101 0 0         if ($frame) {
102 0           print $LINEINFO ' ' x $stack_depth, "$line:\t$dbline[$line]$after";
103             } else {
104 0           print $LINEINFO $position;
105             }
106 0   0       for ($i = $line + 1; $i <= $max && $dbline[$i] == 0; ++$i) { #{ vi
107 0 0         last if $dbline[$i] =~ /^\s*[\;\}\#\n]/;
108 0 0         last if $signal;
109 0 0         $after = ($dbline[$i] =~ /\n$/ ? '' : "\n");
110 0           $incr_pos = "$prefix$i$infix$dbline[$i]$after";
111 0           $position .= $incr_pos;
112 0 0         if ($frame) {
113 0           print $LINEINFO ' ' x $stack_depth, "$i:\t$dbline[$i]$after";
114             } else {
115 0           print $LINEINFO $incr_pos;
116             }
117             }
118             }
119             }
120 0 0         $evalarg = $action, &eval if $action;
121 0 0 0       if ($single || $was_signal) {
122 0           local $level = $level + 1;
123 0           foreach $evalarg (@$pre) {
124 0           &eval;
125             }
126 0 0         print $OUT $stack_depth . " levels deep in subroutine calls!\n"
127             if $single & 4;
128 0           $start = $line;
129 0           $incr = -1; # for backward motion.
130 0           @typeahead = (@$pretype, @typeahead);
131             CMD:
132 0   0       while (($term || &setterm),
      0        
133             ($term_pid == $$ or &resetterm),
134             defined ($cmd=&readline(" DB" . ('<' x $level) .
135             ($#hist+1) . ('>' x $level) .
136             " ")))
137             {
138 0           $single = 0;
139 0           $signal = 0;
140 0 0         $cmd =~ s/\\$/\n/ && do {
141 0           $cmd .= &readline(" cont: ");
142 0           redo CMD;
143             };
144 0 0         $cmd =~ /^$/ && ($cmd = $laststep);
145 0 0         push(@hist,$cmd) if length($cmd) > 1;
146 0           PIPE: {
147 0           $cmd =~ s/^\s+//s; # trim annoying leading whitespace
148 0           $cmd =~ s/\s+$//s; # trim annoying trailing whitespace
149 0           ($i) = split(/\s+/,$cmd);
150 0 0         if ($alias{$i}) {
151             # squelch the sigmangler
152 0           local $SIG{__DIE__};
153 0           local $SIG{__WARN__};
154 0           eval "\$cmd =~ $alias{$i}";
155 0 0         if ($@) {
156 0           print $OUT "Couldn't evaluate `$i' alias: $@";
157 0           next CMD;
158             }
159             }
160              
161             ### Extended commands
162              
163             ### Define your extended commands in C<%commands> at the top of the file.
164             ### This section runs them.
165              
166 0           foreach my $do (keys %DB::commands) {
167 0 0         next unless $cmd =~ /^$do\s*/;
168 0 0         $commands{$do}->($cmd) and next CMD;
169             # ? next CMD : last CMD;
170             }
171              
172 0 0 0       $cmd =~ /^q$/ && ($fall_off_end = 1) && exit $?;
173 0 0         $cmd =~ /^h$/ && do {
174 0           print_help($help);
175 0           next CMD; };
176 0 0         $cmd =~ /^h\s+h$/ && do {
177 0           print_help($summary);
178 0           next CMD; };
179             # support long commands; otherwise bogus errors
180             # happen when you ask for h on for example
181 0 0         $cmd =~ /^h\s+(\S.*)$/ && do {
182 0           my $asked = $1; # for proper errmsg
183 0           my $qasked = quotemeta($asked); # for searching
184             # XXX: finds CR but not
185 0 0         if ($help =~ /^
186 0           while ($help =~ /^(
187 0           print_help($1);
188             }
189             } else {
190 0           print_help("B<$asked> is not a debugger command.\n");
191             }
192 0           next CMD; };
193 0 0         $cmd =~ /^t$/ && do {
194 0           $trace ^= 1;
195 0 0         print $OUT "Trace = " .
196             (($trace & 1) ? "on" : "off" ) . "\n";
197 0           next CMD; };
198 0 0         $cmd =~ /^S(\s+(!)?(.+))?$/ && do {
199 0           $Srev = defined $2; $Spatt = $3; $Snocheck = ! defined $1;
  0            
  0            
200 0           foreach $subname (sort(keys %sub)) {
201 0 0 0       if ($Snocheck or $Srev^($subname =~ /$Spatt/)) {
202 0           print $OUT $subname,"\n";
203             }
204             }
205 0           next CMD; };
206 0 0         $cmd =~ /^v$/ && do {
207 0           list_versions(); next CMD};
  0            
208 0           $cmd =~ s/^X\b/V $package/;
209 0 0         $cmd =~ /^V$/ && do {
210 0           $cmd = "V $package"; };
211 0 0         $cmd =~ /^V\b\s*(\S+)\s*(.*)/ && do {
212 0           local ($savout) = select($OUT);
213 0           $packname = $1;
214 0           @vars = split(' ',$2);
215 0 0         do 'dumpvar.pl' unless defined &main::dumpvar;
216 0 0         if (defined &main::dumpvar) {
217 0           local $frame = 0;
218 0           local $doret = -2;
219             # must detect sigpipe failures
220 0           eval { &main::dumpvar($packname,@vars) };
  0            
221 0 0         if ($@) {
222 0 0         die unless $@ =~ /dumpvar print failed/;
223             }
224             } else {
225 0           print $OUT "dumpvar.pl not available.\n";
226             }
227 0           select ($savout);
228 0           next CMD; };
229 0 0         $cmd =~ s/^x\b/ / && do { # So that will be evaled
230 0           $onetimeDump = 'dump'; };
231 0 0         $cmd =~ s/^m\s+([\w:]+)\s*$/ / && do {
232 0           methods($1); next CMD};
  0            
233 0 0         $cmd =~ s/^m\b/ / && do { # So this will be evaled
234 0           $onetimeDump = 'methods'; };
235 0 0         $cmd =~ /^f\b\s*(.*)/ && do {
236 0           $file = $1;
237 0           $file =~ s/\s+$//;
238 0 0         if (!$file) {
239 0           print $OUT "The old f command is now the r command.\n";
240 0           print $OUT "The new f command switches filenames.\n";
241 0           next CMD;
242             }
243 0 0         if (!defined $main::{'_<' . $file}) {
244 0 0         if (($try) = grep(m#^_<.*$file#, keys %main::)) {{
  0            
245 0           $try = substr($try,2);
246 0           print $OUT "Choosing $try matching `$file':\n";
247 0           $file = $try;
248             }}
249             }
250 0 0         if (!defined $main::{'_<' . $file}) {
    0          
251 0           print $OUT "No file matching `$file' is loaded.\n";
252 0           next CMD;
253             } elsif ($file ne $filename) {
254 0           *dbline = $main::{'_<' . $file};
255 0           $max = $#dbline;
256 0           $filename = $file;
257 0           $start = 1;
258 0           $cmd = "l";
259             } else {
260 0           print $OUT "Already in $file.\n";
261 0           next CMD;
262             }
263             };
264 0           $cmd =~ s/^l\s+-\s*$/-/;
265 0 0         $cmd =~ /^([lb])\b\s*(\$.*)/s && do {
266 0           $evalarg = $2;
267 0           my ($s) = &eval;
268 0 0         print($OUT "Error: $@\n"), next CMD if $@;
269 0           $s = CvGV_name($s);
270 0           print($OUT "Interpreted as: $1 $s\n");
271 0           $cmd = "$1 $s";
272             };
273 0 0         $cmd =~ /^l\b\s*([\':A-Za-z_][\':\w]*(\[.*\])?)/s && do {
274 0           $subname = $1;
275 0           $subname =~ s/\'/::/;
276 0 0         $subname = $package."::".$subname
277             unless $subname =~ /::/;
278 0 0         $subname = "main".$subname if substr($subname,0,2) eq "::";
279 0   0       @pieces = split(/:/,find_sub($subname) || $sub{$subname});
280 0           $subrange = pop @pieces;
281 0           $file = join(':', @pieces);
282 0 0         if ($file ne $filename) {
283 0 0         print $OUT "Switching to file '$file'.\n"
284             unless $slave_editor;
285 0           *dbline = $main::{'_<' . $file};
286 0           $max = $#dbline;
287 0           $filename = $file;
288             }
289 0 0         if ($subrange) {
290 0 0         if (eval($subrange) < -$window) {
291 0           $subrange =~ s/-.*/+/;
292             }
293 0           $cmd = "l $subrange";
294             } else {
295 0           print $OUT "Subroutine $subname not found.\n";
296 0           next CMD;
297             } };
298 0 0         $cmd =~ /^\.$/ && do {
299 0           $incr = -1; # for backward motion.
300 0           $start = $line;
301 0           $filename = $filename_ini;
302 0           *dbline = $main::{'_<' . $filename};
303 0           $max = $#dbline;
304 0           print $LINEINFO $position;
305 0           next CMD };
306 0 0         $cmd =~ /^w\b\s*(\d*)$/ && do {
307 0           $incr = $window - 1;
308 0 0         $start = $1 if $1;
309 0           $start -= $preview;
310             #print $OUT 'l ' . $start . '-' . ($start + $incr);
311 0           $cmd = 'l ' . $start . '-' . ($start + $incr); };
312 0 0         $cmd =~ /^-$/ && do {
313 0           $start -= $incr + $window + 1;
314 0 0         $start = 1 if $start <= 0;
315 0           $incr = $window - 1;
316 0           $cmd = 'l ' . ($start) . '+'; };
317 0 0         $cmd =~ /^l$/ && do {
318 0           $incr = $window - 1;
319 0           $cmd = 'l ' . $start . '-' . ($start + $incr); };
320 0 0         $cmd =~ /^l\b\s*(\d*)\+(\d*)$/ && do {
321 0 0         $start = $1 if $1;
322 0           $incr = $2;
323 0 0         $incr = $window - 1 unless $incr;
324 0           $cmd = 'l ' . $start . '-' . ($start + $incr); };
325 0 0         $cmd =~ /^l\b\s*((-?[\d\$\.]+)([-,]([\d\$\.]+))?)?/ && do {
326 0 0         $end = (!defined $2) ? $max : ($4 ? $4 : $2);
    0          
327 0 0         $end = $max if $end > $max;
328 0           $i = $2;
329 0 0         $i = $line if $i eq '.';
330 0 0         $i = 1 if $i < 1;
331 0           $incr = $end - $i;
332 0 0         if ($slave_editor) {
333 0           print $OUT "\032\032$filename:$i:0\n";
334 0           $i = $end;
335             } else {
336 0           for (; $i <= $end; $i++) {
337 0           ($stop,$action) = split(/\0/, $dbline{$i});
338 0 0 0       $arrow = ($i==$line
    0          
339             and $filename eq $filename_ini)
340             ? '==>'
341             : ($dbline[$i]+0 ? ':' : ' ') ;
342 0 0         $arrow .= 'b' if $stop;
343 0 0         $arrow .= 'a' if $action;
344 0           print $OUT "$i$arrow\t", $dbline[$i];
345 0 0         $i++, last if $signal;
346             }
347 0 0         print $OUT "\n" unless $dbline[$i-1] =~ /\n$/;
348             }
349 0           $start = $i; # remember in case they want more
350 0 0         $start = $max if $start > $max;
351 0           next CMD; };
352 0 0         $cmd =~ /^D$/ && do {
353 0           print $OUT "Deleting all breakpoints...\n";
354 0           my $file;
355 0           for $file (keys %had_breakpoints) {
356 0           local *dbline = $main::{'_<' . $file};
357 0           my $max = $#dbline;
358 0           my $was;
359            
360 0           for ($i = 1; $i <= $max ; $i++) {
361 0 0         if (defined $dbline{$i}) {
362 0           $dbline{$i} =~ s/^[^\0]+//;
363 0 0         if ($dbline{$i} =~ s/^\0?$//) {
364 0           delete $dbline{$i};
365             }
366             }
367             }
368            
369 0 0         if (not $had_breakpoints{$file} &= ~1) {
370 0           delete $had_breakpoints{$file};
371             }
372             }
373 0           undef %postponed;
374 0           undef %postponed_file;
375 0           undef %break_on_load;
376 0           next CMD; };
377 0 0         $cmd =~ /^L$/ && do {
378 0           my $file;
379 0           for $file (keys %had_breakpoints) {
380 0           local *dbline = $main::{'_<' . $file};
381 0           my $max = $#dbline;
382 0           my $was;
383            
384 0           for ($i = 1; $i <= $max; $i++) {
385 0 0         if (defined $dbline{$i}) {
386 0 0         print $OUT "$file:\n" unless $was++;
387 0           print $OUT " $i:\t", $dbline[$i];
388 0           ($stop,$action) = split(/\0/, $dbline{$i});
389 0 0         print $OUT " break if (", $stop, ")\n"
390             if $stop;
391 0 0         print $OUT " action: ", $action, "\n"
392             if $action;
393 0 0         last if $signal;
394             }
395             }
396             }
397 0 0         if (%postponed) {
398 0           print $OUT "Postponed breakpoints in subroutines:\n";
399 0           my $subname;
400 0           for $subname (keys %postponed) {
401 0           print $OUT " $subname\t$postponed{$subname}\n";
402 0 0         last if $signal;
403             }
404             }
405 0           my @have = map { # Combined keys
406 0           keys %{$postponed_file{$_}}
  0            
407             } keys %postponed_file;
408 0 0         if (@have) {
409 0           print $OUT "Postponed breakpoints in files:\n";
410 0           my ($file, $line);
411 0           for $file (keys %postponed_file) {
412 0           my $db = $postponed_file{$file};
413 0           print $OUT " $file:\n";
414 0           for $line (sort {$a <=> $b} keys %$db) {
  0            
415 0           print $OUT " $line:\n";
416 0           my ($stop,$action) = split(/\0/, $$db{$line});
417 0 0         print $OUT " break if (", $stop, ")\n"
418             if $stop;
419 0 0         print $OUT " action: ", $action, "\n"
420             if $action;
421 0 0         last if $signal;
422             }
423 0 0         last if $signal;
424             }
425             }
426 0 0         if (%break_on_load) {
427 0           print $OUT "Breakpoints on load:\n";
428 0           my $file;
429 0           for $file (keys %break_on_load) {
430 0           print $OUT " $file\n";
431 0 0         last if $signal;
432             }
433             }
434 0 0         if ($trace & 2) {
435 0           print $OUT "Watch-expressions:\n";
436 0           my $expr;
437 0           for $expr (@to_watch) {
438 0           print $OUT " $expr\n";
439 0 0         last if $signal;
440             }
441             }
442 0           next CMD; };
443 0 0         $cmd =~ /^b\b\s*load\b\s*(.*)/ && do {
444 0           my $file = $1; $file =~ s/\s+$//;
  0            
445             {
446 0           $break_on_load{$file} = 1;
  0            
447 0 0         $break_on_load{$::INC{$file}} = 1 if $::INC{$file};
448 0 0         $file .= '.pm', redo unless $file =~ /\./;
449             }
450 0           $had_breakpoints{$file} |= 1;
451 0           print $OUT "Will stop on load of `@{[join '\', `', sort keys %break_on_load]}'.\n";
  0            
452 0           next CMD; };
453 0 0         $cmd =~ /^b\b\s*(postpone|compile)\b\s*([':A-Za-z_][':\w]*)\s*(.*)/ && do {
454 0 0         my $cond = length $3 ? $3 : '1';
455 0           my ($subname, $break) = ($2, $1 eq 'postpone');
456 0           $subname =~ s/\'/::/g;
457 0 0         $subname = "${'package'}::" . $subname
  0            
458             unless $subname =~ /::/;
459 0 0         $subname = "main".$subname if substr($subname,0,2) eq "::";
460 0 0         $postponed{$subname} = $break
461             ? "break +0 if $cond" : "compile";
462 0           next CMD; };
463 0 0         $cmd =~ /^b\b\s*([':A-Za-z_][':\w]*(?:\[.*\])?)\s*(.*)/ && do {
464 0           $subname = $1;
465 0 0         $cond = length $2 ? $2 : '1';
466 0           $subname =~ s/\'/::/g;
467 0 0         $subname = "${'package'}::" . $subname
  0            
468             unless $subname =~ /::/;
469 0 0         $subname = "main".$subname if substr($subname,0,2) eq "::";
470             # Filename below can contain ':'
471 0           ($file,$i) = (find_sub($subname) =~ /^(.*):(.*)$/);
472 0           $i += 0;
473 0 0         if ($i) {
474 0           local $filename = $file;
475 0           local *dbline = $main::{'_<' . $filename};
476 0           $had_breakpoints{$filename} |= 1;
477 0           $max = $#dbline;
478 0   0       ++$i while $dbline[$i] == 0 && $i < $max;
479 0           $dbline{$i} =~ s/^[^\0]*/$cond/;
480             } else {
481 0           print $OUT "Subroutine $subname not found.\n";
482             }
483 0           next CMD; };
484 0 0         $cmd =~ /^b\b\s*(\d*)\s*(.*)/ && do {
485 0   0       $i = $1 || $line;
486 0 0         $cond = length $2 ? $2 : '1';
487 0 0         if ($dbline[$i] == 0) {
488 0           print $OUT "Line $i not breakable.\n";
489             } else {
490 0           $had_breakpoints{$filename} |= 1;
491 0           $dbline{$i} =~ s/^[^\0]*/$cond/;
492             }
493 0           next CMD; };
494 0 0         $cmd =~ /^d\b\s*(\d*)/ && do {
495 0   0       $i = $1 || $line;
496 0 0         if ($dbline[$i] == 0) {
497 0           print $OUT "Line $i not breakable.\n";
498             } else {
499 0           $dbline{$i} =~ s/^[^\0]*//;
500 0 0         delete $dbline{$i} if $dbline{$i} eq '';
501             }
502 0           next CMD; };
503 0 0         $cmd =~ /^A$/ && do {
504 0           print $OUT "Deleting all actions...\n";
505 0           my $file;
506 0           for $file (keys %had_breakpoints) {
507 0           local *dbline = $main::{'_<' . $file};
508 0           my $max = $#dbline;
509 0           my $was;
510            
511 0           for ($i = 1; $i <= $max ; $i++) {
512 0 0         if (defined $dbline{$i}) {
513 0           $dbline{$i} =~ s/\0[^\0]*//;
514 0 0         delete $dbline{$i} if $dbline{$i} eq '';
515             }
516             }
517            
518 0 0         unless ($had_breakpoints{$file} &= ~2) {
519 0           delete $had_breakpoints{$file};
520             }
521             }
522 0           next CMD; };
523 0 0         $cmd =~ /^O\s*$/ && do {
524 0           for (@options) {
525 0           &dump_option($_);
526             }
527 0           next CMD; };
528 0 0         $cmd =~ /^O\s*(\S.*)/ && do {
529 0           parse_options($1);
530 0           next CMD; };
531 0 0         $cmd =~ /^\<\<\s*(.*)/ && do { # \<\< for CPerl sake: not HERE
532 0           push @$pre, action($1);
533 0           next CMD; };
534 0 0         $cmd =~ /^>>\s*(.*)/ && do {
535 0           push @$post, action($1);
536 0           next CMD; };
537 0 0         $cmd =~ /^<\s*(.*)/ && do {
538 0 0         unless ($1) {
539 0           print $OUT "All < actions cleared.\n";
540 0           $pre = [];
541 0           next CMD;
542             }
543 0 0         if ($1 eq '?') {
544 0 0         unless (@$pre) {
545 0           print $OUT "No pre-prompt Perl actions.\n";
546 0           next CMD;
547             }
548 0           print $OUT "Perl commands run before each prompt:\n";
549 0           for my $action ( @$pre ) {
550 0           print $OUT "\t< -- $action\n";
551             }
552 0           next CMD;
553             }
554 0           $pre = [action($1)];
555 0           next CMD; };
556 0 0         $cmd =~ /^>\s*(.*)/ && do {
557 0 0         unless ($1) {
558 0           print $OUT "All > actions cleared.\n";
559 0           $post = [];
560 0           next CMD;
561             }
562 0 0         if ($1 eq '?') {
563 0 0         unless (@$post) {
564 0           print $OUT "No post-prompt Perl actions.\n";
565 0           next CMD;
566             }
567 0           print $OUT "Perl commands run after each prompt:\n";
568 0           for my $action ( @$post ) {
569 0           print $OUT "\t> -- $action\n";
570             }
571 0           next CMD;
572             }
573 0           $post = [action($1)];
574 0           next CMD; };
575 0 0         $cmd =~ /^\{\{\s*(.*)/ && do {
576 0 0 0       if ($cmd =~ /^\{.*\}$/ && unbalanced(substr($cmd,2))) {
577 0           print $OUT "{{ is now a debugger command\n",
578             "use `;{{' if you mean Perl code\n";
579 0           $cmd = "h {{";
580 0           redo CMD;
581             }
582 0           push @$pretype, $1;
583 0           next CMD; };
584 0 0         $cmd =~ /^\{\s*(.*)/ && do {
585 0 0         unless ($1) {
586 0           print $OUT "All { actions cleared.\n";
587 0           $pretype = [];
588 0           next CMD;
589             }
590 0 0         if ($1 eq '?') {
591 0 0         unless (@$pretype) {
592 0           print $OUT "No pre-prompt debugger actions.\n";
593 0           next CMD;
594             }
595 0           print $OUT "Debugger commands run before each prompt:\n";
596 0           for my $action ( @$pretype ) {
597 0           print $OUT "\t{ -- $action\n";
598             }
599 0           next CMD;
600             }
601 0 0 0       if ($cmd =~ /^\{.*\}$/ && unbalanced(substr($cmd,1))) {
602 0           print $OUT "{ is now a debugger command\n",
603             "use `;{' if you mean Perl code\n";
604 0           $cmd = "h {";
605 0           redo CMD;
606             }
607 0           $pretype = [$1];
608 0           next CMD; };
609 0 0         $cmd =~ /^a\b\s*(\d*)\s*(.*)/ && do {
610 0   0       $i = $1 || $line; $j = $2;
  0            
611 0 0         if (length $j) {
612 0 0         if ($dbline[$i] == 0) {
613 0           print $OUT "Line $i may not have an action.\n";
614             } else {
615 0           $had_breakpoints{$filename} |= 2;
616 0           $dbline{$i} =~ s/\0[^\0]*//;
617 0           $dbline{$i} .= "\0" . action($j);
618             }
619             } else {
620 0           $dbline{$i} =~ s/\0[^\0]*//;
621 0 0         delete $dbline{$i} if $dbline{$i} eq '';
622             }
623 0           next CMD; };
624 0 0         $cmd =~ /^n$/ && do {
625 0 0 0       end_report(), next CMD if $finished and $level <= 1;
626 0           $single = 2;
627 0           $laststep = $cmd;
628 0           last CMD; };
629 0 0         $cmd =~ /^s$/ && do {
630 0 0 0       end_report(), next CMD if $finished and $level <= 1;
631 0           $single = 1;
632 0           $laststep = $cmd;
633 0           last CMD; };
634 0 0         $cmd =~ /^c\b\s*([\w:]*)\s*$/ && do {
635 0 0 0       end_report(), next CMD if $finished and $level <= 1;
636 0           $subname = $i = $1;
637             # Probably not needed, since we finish an interactive
638             # sub-session anyway...
639             # local $filename = $filename;
640             # local *dbline = *dbline; # XXX Would this work?!
641 0 0         if ($i =~ /\D/) { # subroutine name
642 0 0         $subname = $package."::".$subname
643             unless $subname =~ /::/;
644 0           ($file,$i) = (find_sub($subname) =~ /^(.*):(.*)$/);
645 0           $i += 0;
646 0 0         if ($i) {
647 0           $filename = $file;
648 0           *dbline = $main::{'_<' . $filename};
649 0           $had_breakpoints{$filename} |= 1;
650 0           $max = $#dbline;
651 0   0       ++$i while $dbline[$i] == 0 && $i < $max;
652             } else {
653 0           print $OUT "Subroutine $subname not found.\n";
654 0           next CMD;
655             }
656             }
657 0 0         if ($i) {
658 0 0         if ($dbline[$i] == 0) {
659 0           print $OUT "Line $i not breakable.\n";
660 0           next CMD;
661             }
662 0           $dbline{$i} =~ s/($|\0)/;9$1/; # add one-time-only b.p.
663             }
664 0           for ($i=0; $i <= $stack_depth; ) {
665 0           $stack[$i++] &= ~1;
666             }
667 0           last CMD; };
668 0 0         $cmd =~ /^r$/ && do {
669 0 0 0       end_report(), next CMD if $finished and $level <= 1;
670 0           $stack[$stack_depth] |= 1;
671 0 0         $doret = $option{PrintRet} ? $stack_depth - 1 : -2;
672 0           last CMD; };
673 0 0         $cmd =~ /^R$/ && do {
674 0           print $OUT "Warning: some settings and command-line options may be lost!\n";
675 0           my (@script, @flags, $cl);
676 0 0         push @flags, '-w' if $ini_warn;
677             # Put all the old includes at the start to get
678             # the same debugger.
679 0           for (@ini_INC) {
680 0           push @flags, '-I', $_;
681             }
682             # Arrange for setting the old INC:
683 0           set_list("PERLDB_INC", @ini_INC);
684 0 0         if ($0 eq '-e') {
685 0           for (1..$#{'::_<-e'}) { # The first line is PERL5DB
  0            
686 0           chomp ($cl = ${'::_<-e'}[$_]);
  0            
687 0           push @script, '-e', $cl;
688             }
689             } else {
690 0           @script = $0;
691             }
692 0 0         set_list("PERLDB_HIST",
693             $term->Features->{getHistory}
694             ? $term->GetHistory : @hist);
695 0           my @had_breakpoints = keys %had_breakpoints;
696 0           set_list("PERLDB_VISITED", @had_breakpoints);
697 0           set_list("PERLDB_OPT", %option);
698 0           set_list("PERLDB_ON_LOAD", %break_on_load);
699 0           my @hard;
700 0           for (0 .. $#had_breakpoints) {
701 0           my $file = $had_breakpoints[$_];
702 0           *dbline = $main::{'_<' . $file};
703 0 0 0       next unless %dbline or $postponed_file{$file};
704 0 0         (push @hard, $file), next
705             if $file =~ /^\(eval \d+\)$/;
706 0           my @add;
707 0 0         @add = %{$postponed_file{$file}}
  0            
708             if $postponed_file{$file};
709 0           set_list("PERLDB_FILE_$_", %dbline, @add);
710             }
711 0           for (@hard) { # Yes, really-really...
712             # Find the subroutines in this eval
713 0           *dbline = $main::{'_<' . $_};
714 0           my ($quoted, $sub, %subs, $line) = quotemeta $_;
715 0           for $sub (keys %sub) {
716 0 0         next unless $sub{$sub} =~ /^$quoted:(\d+)-(\d+)$/;
717 0           $subs{$sub} = [$1, $2];
718             }
719 0 0         unless (%subs) {
720 0           print $OUT
721             "No subroutines in $_, ignoring breakpoints.\n";
722 0           next;
723             }
724 0           LINES: for $line (keys %dbline) {
725             # One breakpoint per sub only:
726 0           my ($offset, $sub, $found);
727 0           SUBS: for $sub (keys %subs) {
728 0 0 0       if ($subs{$sub}->[1] >= $line # Not after the subroutine
      0        
729             and (not defined $offset # Not caught
730             or $offset < 0 )) { # or badly caught
731 0           $found = $sub;
732 0           $offset = $line - $subs{$sub}->[0];
733 0 0         $offset = "+$offset", last SUBS if $offset >= 0;
734             }
735             }
736 0 0         if (defined $offset) {
737 0           $postponed{$found} =
738             "break $offset if $dbline{$line}";
739             } else {
740 0           print $OUT "Breakpoint in $_:$line ignored: after all the subroutines.\n";
741             }
742             }
743             }
744 0           set_list("PERLDB_POSTPONE", %postponed);
745 0           set_list("PERLDB_PRETYPE", @$pretype);
746 0           set_list("PERLDB_PRE", @$pre);
747 0           set_list("PERLDB_POST", @$post);
748 0           set_list("PERLDB_TYPEAHEAD", @typeahead);
749 0           $ENV{PERLDB_RESTART} = 1;
750             #print "$^X, '-d', @flags, @script, ($slave_editor ? '-emacs' : ()), @ARGS";
751 0 0         exec $^X, '-d', @flags, @script, ($slave_editor ? '-emacs' : ()), @ARGS;
752 0           print $OUT "exec failed: $!\n";
753 0           last CMD; };
754 0 0         $cmd =~ /^T$/ && do {
755 0           print_trace($OUT, 1); # skip DB
756 0           next CMD; };
757 0 0         $cmd =~ /^W\s*$/ && do {
758 0           $trace &= ~2;
759 0           @to_watch = @old_watch = ();
760 0           next CMD; };
761 0 0         $cmd =~ /^W\b\s*(.*)/s && do {
762 0           push @to_watch, $1;
763 0           $evalarg = $1;
764 0           my ($val) = &eval;
765 0 0         $val = (defined $val) ? "'$val'" : 'undef' ;
766 0           push @old_watch, $val;
767 0           $trace |= 2;
768 0           next CMD; };
769 0 0         $cmd =~ /^\/(.*)$/ && do {
770 0           $inpat = $1;
771 0           $inpat =~ s:([^\\])/$:$1:;
772 0 0         if ($inpat ne "") {
773             # squelch the sigmangler
774 0           local $SIG{__DIE__};
775 0           local $SIG{__WARN__};
776 0           eval '$inpat =~ m'."\a$inpat\a";
777 0 0         if ($@ ne "") {
778 0           print $OUT "$@";
779 0           next CMD;
780             }
781 0           $pat = $inpat;
782             }
783 0           $end = $start;
784 0           $incr = -1;
785 0           eval '
786             for (;;) {
787             ++$start;
788             $start = 1 if ($start > $max);
789             last if ($start == $end);
790             if ($dbline[$start] =~ m' . "\a$pat\a" . 'i) {
791             if ($slave_editor) {
792             print $OUT "\032\032$filename:$start:0\n";
793             } else {
794             print $OUT "$start:\t", $dbline[$start], "\n";
795             }
796             last;
797             }
798             } ';
799 0 0         print $OUT "/$pat/: not found\n" if ($start == $end);
800 0           next CMD; };
801 0 0         $cmd =~ /^\?(.*)$/ && do {
802 0           $inpat = $1;
803 0           $inpat =~ s:([^\\])\?$:$1:;
804 0 0         if ($inpat ne "") {
805             # squelch the sigmangler
806 0           local $SIG{__DIE__};
807 0           local $SIG{__WARN__};
808 0           eval '$inpat =~ m'."\a$inpat\a";
809 0 0         if ($@ ne "") {
810 0           print $OUT $@;
811 0           next CMD;
812             }
813 0           $pat = $inpat;
814             }
815 0           $end = $start;
816 0           $incr = -1;
817 0           eval '
818             for (;;) {
819             --$start;
820             $start = $max if ($start <= 0);
821             last if ($start == $end);
822             if ($dbline[$start] =~ m' . "\a$pat\a" . 'i) {
823             if ($slave_editor) {
824             print $OUT "\032\032$filename:$start:0\n";
825             } else {
826             print $OUT "$start:\t", $dbline[$start], "\n";
827             }
828             last;
829             }
830             } ';
831 0 0         print $OUT "?$pat?: not found\n" if ($start == $end);
832 0           next CMD; };
833 0 0         $cmd =~ /^$rc+\s*(-)?(\d+)?$/ && do {
834 0 0         pop(@hist) if length($cmd) > 1;
835 0 0 0       $i = $1 ? ($#hist-($2||1)) : ($2||$#hist);
      0        
836 0           $cmd = $hist[$i];
837 0           print $OUT $cmd, "\n";
838 0           redo CMD; };
839 0 0         $cmd =~ /^$sh$sh\s*([\x00-\xff]*)/ && do {
840 0           &system($1);
841 0           next CMD; };
842 0 0         $cmd =~ /^$rc([^$rc].*)$/ && do {
843 0           $pat = "^$1";
844 0 0         pop(@hist) if length($cmd) > 1;
845 0           for ($i = $#hist; $i; --$i) {
846 0 0         last if $hist[$i] =~ /$pat/;
847             }
848 0 0         if (!$i) {
849 0           print $OUT "No such command!\n\n";
850 0           next CMD;
851             }
852 0           $cmd = $hist[$i];
853 0           print $OUT $cmd, "\n";
854 0           redo CMD; };
855 0 0         $cmd =~ /^$sh$/ && do {
856 0   0       &system($ENV{SHELL}||"/bin/sh");
857 0           next CMD; };
858 0 0         $cmd =~ /^$sh\s*([\x00-\xff]*)/ && do {
859             # XXX: using csh or tcsh destroys sigint retvals!
860             #&system($1); # use this instead
861 0   0       &system($ENV{SHELL}||"/bin/sh","-c",$1);
862 0           next CMD; };
863 0 0         $cmd =~ /^H\b\s*(-(\d+))?/ && do {
864 0 0         $end = $2 ? ($#hist-$2) : 0;
865 0 0         $hist = 0 if $hist < 0;
866 0           for ($i=$#hist; $i>$end; $i--) {
867 0 0         print $OUT "$i: ",$hist[$i],"\n"
868             unless $hist[$i] =~ /^.?$/;
869             };
870 0           next CMD; };
871 0 0         $cmd =~ /^(?:man|(?:perl)?doc)\b(?:\s+([^(]*))?$/ && do {
872 0           runman($1);
873 0           next CMD; };
874 0           $cmd =~ s/^p$/print {\$DB::OUT} \$_/;
875 0           $cmd =~ s/^p\b/print {\$DB::OUT} /;
876 0 0         $cmd =~ s/^=\s*// && do {
877 0           my @keys;
878 0 0         if (length $cmd == 0) {
    0          
879 0           @keys = sort keys %alias;
880             }
881             elsif (my($k,$v) = ($cmd =~ /^(\S+)\s+(\S.*)/)) {
882             # can't use $_ or kill //g state
883 0           for my $x ($k, $v) { $x =~ s/\a/\\a/g }
  0            
884 0           $alias{$k} = "s\a$k\a$v\a";
885             # squelch the sigmangler
886 0           local $SIG{__DIE__};
887 0           local $SIG{__WARN__};
888 0 0         unless (eval "sub { s\a$k\a$v\a }; 1") {
889 0           print $OUT "Can't alias $k to $v: $@\n";
890 0           delete $alias{$k};
891 0           next CMD;
892             }
893 0           @keys = ($k);
894             }
895             else {
896 0           @keys = ($cmd);
897             }
898 0           for my $k (@keys) {
899 0 0         if ((my $v = $alias{$k}) =~ ss\a$k\a(.*)\a$1) {
    0          
900 0           print $OUT "$k\t= $1\n";
901             }
902             elsif (defined $alias{$k}) {
903 0           print $OUT "$k\t$alias{$k}\n";
904             }
905             else {
906 0           print "No alias for $k\n";
907             }
908             }
909 0           next CMD; };
910 0 0         $cmd =~ /^\|\|?\s*[^|]/ && do {
911 0 0         if ($pager =~ /^\|/) {
912 0 0         open(SAVEOUT,">&STDOUT") || &warn("Can't save STDOUT");
913 0 0         open(STDOUT,">&OUT") || &warn("Can't redirect STDOUT");
914             } else {
915 0 0         open(SAVEOUT,">&OUT") || &warn("Can't save DB::OUT");
916             }
917 0           fix_less();
918 0 0         unless ($piped=open(OUT,$pager)) {
919 0           &warn("Can't pipe output to `$pager'");
920 0 0         if ($pager =~ /^\|/) {
921 0 0         open(OUT,">&STDOUT") # XXX: lost message
922             || &warn("Can't restore DB::OUT");
923 0 0         open(STDOUT,">&SAVEOUT")
924             || &warn("Can't restore STDOUT");
925 0           close(SAVEOUT);
926             } else {
927 0 0         open(OUT,">&STDOUT") # XXX: lost message
928             || &warn("Can't restore DB::OUT");
929             }
930 0           next CMD;
931             }
932 0 0 0       $SIG{PIPE}= \&DB::catch if $pager =~ /^\|/
      0        
933             && ("" eq $SIG{PIPE} || "DEFAULT" eq $SIG{PIPE});
934 0           $selected= select(OUT);
935 0           $|= 1;
936 0 0         select( $selected ), $selected= "" unless $cmd =~ /^\|\|/;
937 0           $cmd =~ s/^\|+\s*//;
938 0           redo PIPE;
939             };
940             # XXX Local variants do not work!
941 0           $cmd =~ s/^t\s/\$DB::trace |= 1;\n/;
942 0 0         $cmd =~ s/^s\s/\$DB::single = 1;\n/ && do {$laststep = 's'};
  0            
943 0 0         $cmd =~ s/^n\s/\$DB::single = 2;\n/ && do {$laststep = 'n'};
  0            
944             } # PIPE:
945 0           $evalarg = "\$^D = \$^D | \$DB::db_stop;\n$cmd"; &eval;
  0            
946 0 0         if ($onetimeDump) {
    0          
947 0           $onetimeDump = undef;
948             } elsif ($term_pid == $$) {
949 0           print $OUT "\n";
950             }
951             } continue { # CMD:
952 0 0         if ($piped) {
953 0 0         if ($pager =~ /^\|/) {
954 0           $? = 0;
955             # we cannot warn here: the handle is missing --tchrist
956 0 0         close(OUT) || print SAVEOUT "\nCan't close DB::OUT\n";
957              
958             # most of the $? crud was coping with broken cshisms
959 0 0         if ($?) {
960 0           print SAVEOUT "Pager `$pager' failed: ";
961 0 0         if ($? == -1) {
    0          
962 0           print SAVEOUT "shell returned -1\n";
963             } elsif ($? >> 8) {
964 0 0         print SAVEOUT
    0          
965             ( $? & 127 ) ? " (SIG#".($?&127).")" : "",
966             ( $? & 128 ) ? " -- core dumped" : "", "\n";
967             } else {
968 0           print SAVEOUT "status ", ($? >> 8), "\n";
969             }
970             }
971              
972 0 0         open(OUT,">&STDOUT") || &warn("Can't restore DB::OUT");
973 0 0         open(STDOUT,">&SAVEOUT") || &warn("Can't restore STDOUT");
974 0 0         $SIG{PIPE} = "DEFAULT" if $SIG{PIPE} eq \&DB::catch;
975             # Will stop ignoring SIGPIPE if done like nohup(1)
976             # does SIGINT but Perl doesn't give us a choice.
977             } else {
978 0 0         open(OUT,">&SAVEOUT") || &warn("Can't restore DB::OUT");
979             }
980 0           close(SAVEOUT);
981 0 0         select($selected), $selected= "" unless $selected eq "";
982 0           $piped= "";
983             }
984             } # CMD:
985 0 0         $fall_off_end = 1 unless defined $cmd; # Emulate `q' on EOF
986 0           foreach $evalarg (@$post) {
987 0           &eval;
988             }
989             } # if ($single || $signal)
990 0           ($@, $!, $^E, $,, $/, $\, $^W) = @saved;
991 0           ();
992             }
993              
994             }
995              
996             1;
997              
998             __END__