File Coverage

blib/lib/Devel/Command/DBSub/DB_5_8_5.pm
Criterion Covered Total %
statement 9 427 2.1
branch 2 310 0.6
condition 1 85 1.1
subroutine 3 4 75.0
pod 0 1 0.0
total 15 827 1.8


line stmt bran cond sub pod time code
1             package Devel::Command::DBSub::DB_5_8_5;
2              
3             sub import {
4 1 50 33 1   13 if (my($sub_version) =
5             # 5.9.1 is also this version of the debugger
6             ($] =~ /^5.008(.*)/ or
7             $] eq '5.009001'
8             )
9             ) {
10             # This module might work.
11 1 50       4 if ($sub_version+0 <= 5) {
12 1         5 return \&DB::alt_585_DB;
13             }
14             else {
15             # Not 5.8.5 or less.
16 0           return;
17             }
18             }
19             else {
20             # not 5.8 at all.
21 0           return;
22             }
23             }
24              
25             {
26 1     1   1419 no strict;
  1         2  
  1         33  
27 1     1   5 no warnings;
  1         1  
  1         6743  
28             package DB;
29              
30             sub alt_585_DB {
31              
32             # Check for whether we should be running continuously or not.
33             # _After_ the perl program is compiled, $single is set to 1:
34 0 0 0 0 0   if ( $single and not $second_time++ ) {
35              
36             # Options say run non-stop. Run until we get an interrupt.
37 0 0         if ($runnonstop) { # Disable until signal
    0          
38             # If there's any call stack in place, turn off single
39             # stepping into subs throughout the stack.
40 0           for ( $i = 0 ; $i <= $stack_depth ; ) {
41 0           $stack[ $i++ ] &= ~1;
42             }
43              
44             # And we are now no longer in single-step mode.
45 0           $single = 0;
46              
47             # If we simply returned at this point, we wouldn't get
48             # the trace info. Fall on through.
49             # return;
50             } ## end if ($runnonstop)
51              
52             elsif ($ImmediateStop) {
53              
54             # We are supposed to stop here; XXX probably a break.
55 0           $ImmediateStop = 0; # We've processed it; turn it off
56 0           $signal = 1; # Simulate an interrupt to force
57             # us into the command loop
58             }
59             } ## end if ($single and not $second_time...
60              
61             # If we're in single-step mode, or an interrupt (real or fake)
62             # has occurred, turn off non-stop mode.
63 0 0 0       $runnonstop = 0 if $single or $signal;
64              
65             # Preserve current values of $@, $!, $^E, $,, $/, $\, $^W.
66             # The code being debugged may have altered them.
67 0           &save;
68              
69             # Since DB::DB gets called after every line, we can use caller() to
70             # figure out where we last were executing. Sneaky, eh? This works because
71             # caller is returning all the extra information when called from the
72             # debugger.
73 0           local ( $package, $filename, $line ) = caller;
74 0           local $filename_ini = $filename;
75              
76             # set up the context for DB::eval, so it can properly execute
77             # code on behalf of the user. We add the package in so that the
78             # code is eval'ed in the proper package (not in the debugger!).
79 0           local $usercontext =
80             '($@, $!, $^E, $,, $/, $\, $^W) = @saved;' . "package $package;";
81              
82             # Create an alias to the active file magical array to simplify
83             # the code here.
84 0           local (*dbline) = $main::{ '_<' . $filename };
85              
86             # we need to check for pseudofiles on Mac OS (these are files
87             # not attached to a filename, but instead stored in Dev:Pseudo)
88 0 0 0       if ( $^O eq 'MacOS' && $#dbline < 0 ) {
89 0           $filename_ini = $filename = 'Dev:Pseudo';
90 0           *dbline = $main::{ '_<' . $filename };
91             }
92              
93             # Last line in the program.
94 0           local $max = $#dbline;
95              
96             # if we have something here, see if we should break.
97 0 0 0       if ( $dbline{$line}
98             && ( ( $stop, $action ) = split( /\0/, $dbline{$line} ) ) )
99             {
100              
101             # Stop if the stop criterion says to just stop.
102 0 0         if ( $stop eq '1' ) {
    0          
103 0           $signal |= 1;
104             }
105              
106             # It's a conditional stop; eval it in the user's context and
107             # see if we should stop. If so, remove the one-time sigil.
108             elsif ($stop) {
109 0           $evalarg = "\$DB::signal |= 1 if do {$stop}";
110 0           &eval;
111 0           $dbline{$line} =~ s/;9($|\0)/$1/;
112             }
113             } ## end if ($dbline{$line} && ...
114              
115             # Preserve the current stop-or-not, and see if any of the W
116             # (watch expressions) has changed.
117 0           my $was_signal = $signal;
118              
119             # If we have any watch expressions ...
120 0 0         if ( $trace & 2 ) {
121 0           for ( my $n = 0 ; $n <= $#to_watch ; $n++ ) {
122 0           $evalarg = $to_watch[$n];
123 0           local $onetimeDump; # Tell DB::eval() to not output results
124              
125             # Fix context DB::eval() wants to return an array, but
126             # we need a scalar here.
127 0           my ($val) = join( "', '", &eval );
128 0 0         $val = ( ( defined $val ) ? "'$val'" : 'undef' );
129              
130             # Did it change?
131 0 0         if ( $val ne $old_watch[$n] ) {
132              
133             # Yep! Show the difference, and fake an interrupt.
134 0           $signal = 1;
135 0           print $OUT <
136             Watchpoint $n:\t$to_watch[$n] changed:
137             old value:\t$old_watch[$n]
138             new value:\t$val
139             EOP
140 0           $old_watch[$n] = $val;
141             } ## end if ($val ne $old_watch...
142             } ## end for (my $n = 0 ; $n <= ...
143             } ## end if ($trace & 2)
144              
145             # If there's a user-defined DB::watchfunction, call it with the
146             # current package, filename, and line. The function executes in
147             # the DB:: package.
148 0 0         if ( $trace & 4 ) { # User-installed watch
149             return
150 0 0 0       if watchfunction( $package, $filename, $line )
      0        
      0        
151             and not $single
152             and not $was_signal
153             and not( $trace & ~4 );
154             } ## end if ($trace & 4)
155              
156             # Pick up any alteration to $signal in the watchfunction, and
157             # turn off the signal now.
158 0           $was_signal = $signal;
159 0           $signal = 0;
160              
161             # Check to see if we should grab control ($single true,
162             # trace set appropriately, or we got a signal).
163 0 0 0       if ( $single || ( $trace & 1 ) || $was_signal ) {
      0        
164              
165             # Yes, grab control.
166 0 0         if ($slave_editor) {
    0          
167              
168             # Tell the editor to update its position.
169 0           $position = "\032\032$filename:$line:0\n";
170 0           print_lineinfo($position);
171             }
172              
173             elsif ( $package eq 'DB::fake' ) {
174              
175             # Fallen off the end already.
176 0 0         $term || &setterm;
177 0           print_help(<
178             Debugged program terminated. Use B to quit or B to restart,
179             use B I to avoid stopping after program termination,
180             B, B or B to get additional info.
181             EOP
182              
183             # Set the DB::eval context appropriately.
184 0           $package = 'main';
185 0           $usercontext =
186             '($@, $!, $^E, $,, $/, $\, $^W) = @saved;'
187             . "package $package;"; # this won't let them modify, alas
188             } ## end elsif ($package eq 'DB::fake')
189              
190              
191             else {
192              
193             # Still somewhere in the midst of execution. Set up the
194             # debugger prompt.
195 0           $sub =~ s/\'/::/; # Swap Perl 4 package separators (') to
196             # Perl 5 ones (sorry, we don't print Klingon
197             #module names)
198              
199 0 0         $prefix = $sub =~ /::/ ? "" : "${'package'}::";
  0            
200 0           $prefix .= "$sub($filename:";
201 0 0         $after = ( $dbline[$line] =~ /\n$/ ? '' : "\n" );
202              
203             # Break up the prompt if it's really long.
204 0 0         if ( length($prefix) > 30 ) {
205 0           $position = "$prefix$line):\n$line:\t$dbline[$line]$after";
206 0           $prefix = "";
207 0           $infix = ":\t";
208             }
209             else {
210 0           $infix = "):\t";
211 0           $position = "$prefix$line$infix$dbline[$line]$after";
212             }
213              
214             # Print current line info, indenting if necessary.
215 0 0         if ($frame) {
216 0           print_lineinfo( ' ' x $stack_depth,
217             "$line:\t$dbline[$line]$after" );
218             }
219             else {
220 0           print_lineinfo($position);
221             }
222              
223             # Scan forward, stopping at either the end or the next
224             # unbreakable line.
225 0   0       for ( $i = $line + 1 ; $i <= $max && $dbline[$i] == 0 ; ++$i )
226             { #{ vi
227              
228             # Drop out on null statements, block closers, and comments.
229 0 0         last if $dbline[$i] =~ /^\s*[\;\}\#\n]/;
230              
231             # Drop out if the user interrupted us.
232 0 0         last if $signal;
233              
234             # Append a newline if the line doesn't have one. Can happen
235             # in eval'ed text, for instance.
236 0 0         $after = ( $dbline[$i] =~ /\n$/ ? '' : "\n" );
237              
238             # Next executable line.
239 0           $incr_pos = "$prefix$i$infix$dbline[$i]$after";
240 0           $position .= $incr_pos;
241 0 0         if ($frame) {
242              
243             # Print it indented if tracing is on.
244 0           print_lineinfo( ' ' x $stack_depth,
245             "$i:\t$dbline[$i]$after" );
246             }
247             else {
248 0           print_lineinfo($incr_pos);
249             }
250             } ## end for ($i = $line + 1 ; $i...
251             } ## end else [ if ($slave_editor)
252             } ## end if ($single || ($trace...
253              
254              
255             # If there's an action, do it now.
256 0 0         $evalarg = $action, &eval if $action;
257              
258             # Are we nested another level (e.g., did we evaluate a function
259             # that had a breakpoint in it at the debugger prompt)?
260 0 0 0       if ( $single || $was_signal ) {
261              
262             # Yes, go down a level.
263 0           local $level = $level + 1;
264              
265             # Do any pre-prompt actions.
266 0           foreach $evalarg (@$pre) {
267 0           &eval;
268             }
269              
270             # Complain about too much recursion if we passed the limit.
271 0 0         print $OUT $stack_depth . " levels deep in subroutine calls!\n"
272             if $single & 4;
273              
274             # The line we're currently on. Set $incr to -1 to stay here
275             # until we get a command that tells us to advance.
276 0           $start = $line;
277 0           $incr = -1; # for backward motion.
278              
279             # Tack preprompt debugger actions ahead of any actual input.
280 0           @typeahead = ( @$pretype, @typeahead );
281              
282             # The big command dispatch loop. It keeps running until the
283             # user yields up control again.
284             #
285             # If we have a terminal for input, and we get something back
286             # from readline(), keep on processing.
287             CMD:
288 0   0       while (
      0        
289              
290             # We have a terminal, or can get one ...
291             ( $term || &setterm ),
292              
293             # ... and it belogs to this PID or we get one for this PID ...
294             ( $term_pid == $$ or resetterm(1) ),
295              
296             # ... and we got a line of command input ...
297             defined(
298             $cmd = &readline(
299             "$pidprompt DB"
300             . ( '<' x $level )
301             . ( $#hist + 1 )
302             . ( '>' x $level ) . " "
303             )
304             )
305             )
306             {
307              
308             # ... try to execute the input as debugger commands.
309              
310             # Don't stop running.
311 0           $single = 0;
312              
313             # No signal is active.
314 0           $signal = 0;
315              
316             # Handle continued commands (ending with \):
317 0 0         $cmd =~ s/\\$/\n/ && do {
318 0           $cmd .= &readline(" cont: ");
319 0           redo CMD;
320             };
321              
322             # Empty input means repeat the last command.
323 0 0         $cmd =~ /^$/ && ( $cmd = $laststep );
324 0           chomp($cmd); # get rid of the annoying extra newline
325 0 0         push( @hist, $cmd ) if length($cmd) > 1;
326 0           push( @truehist, $cmd );
327              
328             # This is a restart point for commands that didn't arrive
329             # via direct user input. It allows us to 'redo PIPE' to
330             # re-execute command processing without reading a new command.
331 0           PIPE: {
332 0           $cmd =~ s/^\s+//s; # trim annoying leading whitespace
333 0           $cmd =~ s/\s+$//s; # trim annoying trailing whitespace
334 0           ($i) = split( /\s+/, $cmd );
335              
336             # See if there's an alias for the command, and set it up if so.
337 0 0         if ( $alias{$i} ) {
338              
339             # Squelch signal handling; we want to keep control here
340             # if something goes loco during the alias eval.
341 0           local $SIG{__DIE__};
342 0           local $SIG{__WARN__};
343              
344             # This is a command, so we eval it in the DEBUGGER's
345             # scope! Otherwise, we can't see the special debugger
346             # variables, or get to the debugger's subs. (Well, we
347             # _could_, but why make it even more complicated?)
348 0           eval "\$cmd =~ $alias{$i}";
349 0 0         if ($@) {
350 0           local $\ = '';
351 0           print $OUT "Couldn't evaluate `$i' alias: $@";
352 0           next CMD;
353             }
354             } ## end if ($alias{$i})
355              
356             ### Extended commands
357              
358             ### Define your extended commands in C<%commands> at the top of the file.
359             ### This section runs them.
360              
361 0           foreach my $do (keys %DB::commands) {
362 0 0         next unless $cmd =~ /^$do\s*/;
363 0 0         $commands{$do}->($cmd) and next CMD;
364             # ? next CMD : last CMD;
365             }
366              
367 0 0         $cmd =~ /^q$/ && do {
368 0           $fall_off_end = 1;
369 0           clean_ENV();
370 0           exit $?;
371             };
372              
373 0 0         $cmd =~ /^t$/ && do {
374 0           $trace ^= 1;
375 0           local $\ = '';
376 0 0         print $OUT "Trace = "
377             . ( ( $trace & 1 ) ? "on" : "off" ) . "\n";
378 0           next CMD;
379             };
380              
381 0 0         $cmd =~ /^S(\s+(!)?(.+))?$/ && do {
382              
383 0           $Srev = defined $2; # Reverse scan?
384 0           $Spatt = $3; # The pattern (if any) to use.
385 0           $Snocheck = !defined $1; # No args - print all subs.
386              
387             # Need to make these sane here.
388 0           local $\ = '';
389 0           local $, = '';
390              
391             # Search through the debugger's magical hash of subs.
392             # If $nocheck is true, just print the sub name.
393             # Otherwise, check it against the pattern. We then use
394             # the XOR trick to reverse the condition as required.
395 0           foreach $subname ( sort( keys %sub ) ) {
396 0 0 0       if ( $Snocheck or $Srev ^ ( $subname =~ /$Spatt/ ) ) {
397 0           print $OUT $subname, "\n";
398             }
399             }
400 0           next CMD;
401             };
402              
403              
404 0           $cmd =~ s/^X\b/V $package/;
405              
406              
407             # Bare V commands get the currently-being-debugged package
408             # added.
409 0 0         $cmd =~ /^V$/ && do {
410 0           $cmd = "V $package";
411             };
412              
413             # V - show variables in package.
414 0 0         $cmd =~ /^V\b\s*(\S+)\s*(.*)/ && do {
415              
416             # Save the currently selected filehandle and
417             # force output to debugger's filehandle (dumpvar
418             # just does "print" for output).
419 0           local ($savout) = select($OUT);
420              
421             # Grab package name and variables to dump.
422 0           $packname = $1;
423 0           @vars = split( ' ', $2 );
424              
425             # If main::dumpvar isn't here, get it.
426 0 0         do 'dumpvar.pl' unless defined &main::dumpvar;
427 0 0         if ( defined &main::dumpvar ) {
428              
429             # We got it. Turn off subroutine entry/exit messages
430             # for the moment, along with return values.
431 0           local $frame = 0;
432 0           local $doret = -2;
433              
434             # must detect sigpipe failures - not catching
435             # then will cause the debugger to die.
436 0           eval {
437 0 0         &main::dumpvar(
438             $packname,
439             defined $option{dumpDepth}
440             ? $option{dumpDepth}
441             : -1, # assume -1 unless specified
442             @vars
443             );
444             };
445              
446             # The die doesn't need to include the $@, because
447             # it will automatically get propagated for us.
448 0 0         if ($@) {
449 0 0         die unless $@ =~ /dumpvar print failed/;
450             }
451             } ## end if (defined &main::dumpvar)
452             else {
453              
454             # Couldn't load dumpvar.
455 0           print $OUT "dumpvar.pl not available.\n";
456             }
457              
458             # Restore the output filehandle, and go round again.
459 0           select($savout);
460 0           next CMD;
461             };
462              
463 0 0         $cmd =~ s/^x\b/ / && do { # Remainder gets done by DB::eval()
464 0           $onetimeDump = 'dump'; # main::dumpvar shows the output
465              
466             # handle special "x 3 blah" syntax XXX propagate
467             # doc back to special variables.
468 0 0         if ( $cmd =~ s/^\s*(\d+)(?=\s)/ / ) {
469 0           $onetimedumpDepth = $1;
470             }
471             };
472              
473 0 0         $cmd =~ s/^m\s+([\w:]+)\s*$/ / && do {
474 0           methods($1);
475 0           next CMD;
476             };
477              
478             # m expr - set up DB::eval to do the work
479 0 0         $cmd =~ s/^m\b/ / && do { # Rest gets done by DB::eval()
480 0           $onetimeDump = 'methods'; # method output gets used there
481             };
482              
483 0 0         $cmd =~ /^f\b\s*(.*)/ && do {
484 0           $file = $1;
485 0           $file =~ s/\s+$//;
486              
487             # help for no arguments (old-style was return from sub).
488 0 0         if ( !$file ) {
489 0           print $OUT
490             "The old f command is now the r command.\n"; # hint
491 0           print $OUT "The new f command switches filenames.\n";
492 0           next CMD;
493             } ## end if (!$file)
494              
495             # if not in magic file list, try a close match.
496 0 0         if ( !defined $main::{ '_<' . $file } ) {
497 0 0         if ( ($try) = grep( m#^_<.*$file#, keys %main:: ) ) {
498             {
499 0           $try = substr( $try, 2 );
  0            
500 0           print $OUT "Choosing $try matching `$file':\n";
501 0           $file = $try;
502             }
503             } ## end if (($try) = grep(m#^_<.*$file#...
504             } ## end if (!defined $main::{ ...
505              
506             # If not successfully switched now, we failed.
507 0 0         if ( !defined $main::{ '_<' . $file } ) {
    0          
508 0           print $OUT "No file matching `$file' is loaded.\n";
509 0           next CMD;
510             }
511              
512             # We switched, so switch the debugger internals around.
513             elsif ( $file ne $filename ) {
514 0           *dbline = $main::{ '_<' . $file };
515 0           $max = $#dbline;
516 0           $filename = $file;
517 0           $start = 1;
518 0           $cmd = "l";
519             } ## end elsif ($file ne $filename)
520              
521             # We didn't switch; say we didn't.
522             else {
523 0           print $OUT "Already in $file.\n";
524 0           next CMD;
525             }
526             };
527              
528             # . command.
529 0 0         $cmd =~ /^\.$/ && do {
530 0           $incr = -1; # stay at current line
531              
532             # Reset everything to the old location.
533 0           $start = $line;
534 0           $filename = $filename_ini;
535 0           *dbline = $main::{ '_<' . $filename };
536 0           $max = $#dbline;
537              
538             # Now where are we?
539 0           print_lineinfo($position);
540 0           next CMD;
541             };
542              
543             # - - back a window.
544 0 0         $cmd =~ /^-$/ && do {
545              
546             # back up by a window; go to 1 if back too far.
547 0           $start -= $incr + $window + 1;
548 0 0         $start = 1 if $start <= 0;
549 0           $incr = $window - 1;
550              
551             # Generate and execute a "l +" command (handled below).
552 0           $cmd = 'l ' . ($start) . '+';
553             };
554              
555             # All of these commands were remapped in perl 5.8.0;
556             # we send them off to the secondary dispatcher (see below).
557 0 0         $cmd =~ /^([aAbBhilLMoOPvwW]\b|[<>\{]{1,2})\s*(.*)/so && do {
558 0           &cmd_wrapper( $1, $2, $line );
559 0           next CMD;
560             };
561              
562              
563 0 0         $cmd =~ /^y(?:\s+(\d*)\s*(.*))?$/ && do {
564              
565             # See if we've got the necessary support.
566 0 0 0       eval { require PadWalker; PadWalker->VERSION(0.08) }
  0 0          
  0            
567             or &warn(
568             $@ =~ /locate/
569             ? "PadWalker module not found - please install\n"
570             : $@
571             )
572             and next CMD;
573              
574             # Load up dumpvar if we don't have it. If we can, that is.
575 0 0         do 'dumpvar.pl' unless defined &main::dumpvar;
576 0 0 0       defined &main::dumpvar
577             or print $OUT "dumpvar.pl not available.\n"
578             and next CMD;
579              
580             # Got all the modules we need. Find them and print them.
581 0   0       my @vars = split( ' ', $2 || '' );
582              
583             # Find the pad.
584 0   0       my $h = eval { PadWalker::peek_my( ( $1 || 0 ) + 1 ) };
  0            
585              
586             # Oops. Can't find it.
587 0 0         $@ and $@ =~ s/ at .*//, &warn($@), next CMD;
588              
589             # Show the desired vars with dumplex().
590 0           my $savout = select($OUT);
591              
592             # Have dumplex dump the lexicals.
593             dumpvar::dumplex( $_, $h->{$_},
594             defined $option{dumpDepth} ? $option{dumpDepth} : -1,
595             @vars )
596 0 0         for sort keys %$h;
597 0           select($savout);
598 0           next CMD;
599             };
600              
601             # n - next
602 0 0         $cmd =~ /^n$/ && do {
603 0 0 0       end_report(), next CMD if $finished and $level <= 1;
604              
605             # Single step, but don't enter subs.
606 0           $single = 2;
607              
608             # Save for empty command (repeat last).
609 0           $laststep = $cmd;
610 0           last CMD;
611             };
612              
613             # s - single step.
614 0 0         $cmd =~ /^s$/ && do {
615              
616             # Get out and restart the command loop if program
617             # has finished.
618 0 0 0       end_report(), next CMD if $finished and $level <= 1;
619              
620             # Single step should enter subs.
621 0           $single = 1;
622              
623             # Save for empty command (repeat last).
624 0           $laststep = $cmd;
625 0           last CMD;
626             };
627              
628              
629             # c - start continuous execution.
630 0 0         $cmd =~ /^c\b\s*([\w:]*)\s*$/ && do {
631              
632             # Hey, show's over. The debugged program finished
633             # executing already.
634 0 0 0       end_report(), next CMD if $finished and $level <= 1;
635              
636             # Capture the place to put a one-time break.
637 0           $subname = $i = $1;
638              
639             # Probably not needed, since we finish an interactive
640             # sub-session anyway...
641             # local $filename = $filename;
642             # local *dbline = *dbline; # XXX Would this work?!
643             #
644             # The above question wonders if localizing the alias
645             # to the magic array works or not. Since it's commented
646             # out, we'll just leave that to speculation for now.
647              
648             # If the "subname" isn't all digits, we'll assume it
649             # is a subroutine name, and try to find it.
650 0 0         if ( $subname =~ /\D/ ) { # subroutine name
651             # Qualify it to the current package unless it's
652             # already qualified.
653 0 0         $subname = $package . "::" . $subname
654             unless $subname =~ /::/;
655              
656             # find_sub will return "file:line_number" corresponding
657             # to where the subroutine is defined; we call find_sub,
658             # break up the return value, and assign it in one
659             # operation.
660 0           ( $file, $i ) = ( find_sub($subname) =~ /^(.*):(.*)$/ );
661              
662             # Force the line number to be numeric.
663 0           $i += 0;
664              
665             # If we got a line number, we found the sub.
666 0 0         if ($i) {
667              
668             # Switch all the debugger's internals around so
669             # we're actually working with that file.
670 0           $filename = $file;
671 0           *dbline = $main::{ '_<' . $filename };
672              
673             # Mark that there's a breakpoint in this file.
674 0           $had_breakpoints{$filename} |= 1;
675              
676             # Scan forward to the first executable line
677             # after the 'sub whatever' line.
678 0           $max = $#dbline;
679 0   0       ++$i while $dbline[$i] == 0 && $i < $max;
680             } ## end if ($i)
681              
682             # We didn't find a sub by that name.
683             else {
684 0           print $OUT "Subroutine $subname not found.\n";
685 0           next CMD;
686             }
687             } ## end if ($subname =~ /\D/)
688              
689             # At this point, either the subname was all digits (an
690             # absolute line-break request) or we've scanned through
691             # the code following the definition of the sub, looking
692             # for an executable, which we may or may not have found.
693             #
694             # If $i (which we set $subname from) is non-zero, we
695             # got a request to break at some line somewhere. On
696             # one hand, if there wasn't any real subroutine name
697             # involved, this will be a request to break in the current
698             # file at the specified line, so we have to check to make
699             # sure that the line specified really is breakable.
700             #
701             # On the other hand, if there was a subname supplied, the
702             # preceeding block has moved us to the proper file and
703             # location within that file, and then scanned forward
704             # looking for the next executable line. We have to make
705             # sure that one was found.
706             #
707             # On the gripping hand, we can't do anything unless the
708             # current value of $i points to a valid breakable line.
709             # Check that.
710 0 0         if ($i) {
711              
712             # Breakable?
713 0 0         if ( $dbline[$i] == 0 ) {
714 0           print $OUT "Line $i not breakable.\n";
715 0           next CMD;
716             }
717              
718             # Yes. Set up the one-time-break sigil.
719 0           $dbline{$i} =~ s/($|\0)/;9$1/; # add one-time-only b.p.
720             } ## end if ($i)
721              
722             # Turn off stack tracing from here up.
723 0           for ( $i = 0 ; $i <= $stack_depth ; ) {
724 0           $stack[ $i++ ] &= ~1;
725             }
726 0           last CMD;
727             };
728              
729             # r - return from the current subroutine.
730 0 0         $cmd =~ /^r$/ && do {
731              
732             # Can't do anythign if the program's over.
733 0 0 0       end_report(), next CMD if $finished and $level <= 1;
734              
735             # Turn on stack trace.
736 0           $stack[$stack_depth] |= 1;
737              
738             # Print return value unless the stack is empty.
739 0 0         $doret = $option{PrintRet} ? $stack_depth - 1 : -2;
740 0           last CMD;
741             };
742              
743 0 0         $cmd =~ /^T$/ && do {
744 0           print_trace( $OUT, 1 ); # skip DB
745 0           next CMD;
746             };
747              
748 0 0         $cmd =~ /^w\b\s*(.*)/s && do { &cmd_w( 'w', $1 ); next CMD; };
  0            
  0            
749              
750 0 0         $cmd =~ /^W\b\s*(.*)/s && do { &cmd_W( 'W', $1 ); next CMD; };
  0            
  0            
751              
752 0 0         $cmd =~ /^\/(.*)$/ && do {
753              
754             # The pattern as a string.
755 0           $inpat = $1;
756              
757             # Remove the final slash.
758 0           $inpat =~ s:([^\\])/$:$1:;
759              
760             # If the pattern isn't null ...
761 0 0         if ( $inpat ne "" ) {
762              
763             # Turn of warn and die procesing for a bit.
764 0           local $SIG{__DIE__};
765 0           local $SIG{__WARN__};
766              
767             # Create the pattern.
768 0           eval '$inpat =~ m' . "\a$inpat\a";
769 0 0         if ( $@ ne "" ) {
770              
771             # Oops. Bad pattern. No biscuit.
772             # Print the eval error and go back for more
773             # commands.
774 0           print $OUT "$@";
775 0           next CMD;
776             }
777 0           $pat = $inpat;
778             } ## end if ($inpat ne "")
779              
780             # Set up to stop on wrap-around.
781 0           $end = $start;
782              
783             # Don't move off the current line.
784 0           $incr = -1;
785              
786             # Done in eval so nothing breaks if the pattern
787             # does something weird.
788 0           eval '
789             for (;;) {
790             # Move ahead one line.
791             ++$start;
792              
793             # Wrap if we pass the last line.
794             $start = 1 if ($start > $max);
795              
796             # Stop if we have gotten back to this line again,
797             last if ($start == $end);
798              
799             # A hit! (Note, though, that we are doing
800             # case-insensitive matching. Maybe a qr//
801             # expression would be better, so the user could
802             # do case-sensitive matching if desired.
803             if ($dbline[$start] =~ m' . "\a$pat\a" . 'i) {
804             if ($slave_editor) {
805             # Handle proper escaping in the slave.
806             print $OUT "\032\032$filename:$start:0\n";
807             }
808             else {
809             # Just print the line normally.
810             print $OUT "$start:\t",$dbline[$start],"\n";
811             }
812             # And quit since we found something.
813             last;
814             }
815             } ';
816              
817             # If we wrapped, there never was a match.
818 0 0         print $OUT "/$pat/: not found\n" if ( $start == $end );
819 0           next CMD;
820             };
821              
822             # ? - backward pattern search.
823 0 0         $cmd =~ /^\?(.*)$/ && do {
824              
825             # Get the pattern, remove trailing question mark.
826 0           $inpat = $1;
827 0           $inpat =~ s:([^\\])\?$:$1:;
828              
829             # If we've got one ...
830 0 0         if ( $inpat ne "" ) {
831              
832             # Turn off die & warn handlers.
833 0           local $SIG{__DIE__};
834 0           local $SIG{__WARN__};
835 0           eval '$inpat =~ m' . "\a$inpat\a";
836              
837 0 0         if ( $@ ne "" ) {
838              
839             # Ouch. Not good. Print the error.
840 0           print $OUT $@;
841 0           next CMD;
842             }
843 0           $pat = $inpat;
844             } ## end if ($inpat ne "")
845              
846             # Where we are now is where to stop after wraparound.
847 0           $end = $start;
848              
849             # Don't move away from this line.
850 0           $incr = -1;
851              
852             # Search inside the eval to prevent pattern badness
853             # from killing us.
854 0           eval '
855             for (;;) {
856             # Back up a line.
857             --$start;
858              
859             # Wrap if we pass the first line.
860              
861             $start = $max if ($start <= 0);
862              
863             # Quit if we get back where we started,
864             last if ($start == $end);
865              
866             # Match?
867             if ($dbline[$start] =~ m' . "\a$pat\a" . 'i) {
868             if ($slave_editor) {
869             # Yep, follow slave editor requirements.
870             print $OUT "\032\032$filename:$start:0\n";
871             }
872             else {
873             # Yep, just print normally.
874             print $OUT "$start:\t",$dbline[$start],"\n";
875             }
876              
877             # Found, so done.
878             last;
879             }
880             } ';
881              
882             # Say we failed if the loop never found anything,
883 0 0         print $OUT "?$pat?: not found\n" if ( $start == $end );
884 0           next CMD;
885             };
886              
887             # $rc - recall command.
888 0 0         $cmd =~ /^$rc+\s*(-)?(\d+)?$/ && do {
889              
890             # No arguments, take one thing off history.
891 0 0         pop(@hist) if length($cmd) > 1;
892              
893             # Relative (- found)?
894             # Y - index back from most recent (by 1 if bare minus)
895             # N - go to that particular command slot or the last
896             # thing if nothing following.
897 0 0 0       $i = $1 ? ( $#hist - ( $2 || 1 ) ) : ( $2 || $#hist );
      0        
898              
899             # Pick out the command desired.
900 0           $cmd = $hist[$i];
901              
902             # Print the command to be executed and restart the loop
903             # with that command in the buffer.
904 0           print $OUT $cmd, "\n";
905 0           redo CMD;
906             };
907              
908             # $sh$sh - run a shell command (if it's all ASCII).
909             # Can't run shell commands with Unicode in the debugger, hmm.
910 0 0         $cmd =~ /^$sh$sh\s*([\x00-\xff]*)/ && do {
911              
912             # System it.
913 0           &system($1);
914 0           next CMD;
915             };
916              
917             # $rc pattern $rc - find a command in the history.
918 0 0         $cmd =~ /^$rc([^$rc].*)$/ && do {
919              
920             # Create the pattern to use.
921 0           $pat = "^$1";
922              
923             # Toss off last entry if length is >1 (and it always is).
924 0 0         pop(@hist) if length($cmd) > 1;
925              
926             # Look backward through the history.
927 0           for ( $i = $#hist ; $i ; --$i ) {
928              
929             # Stop if we find it.
930 0 0         last if $hist[$i] =~ /$pat/;
931             }
932              
933 0 0         if ( !$i ) {
934              
935             # Never found it.
936 0           print $OUT "No such command!\n\n";
937 0           next CMD;
938             }
939              
940             # Found it. Put it in the buffer, print it, and process it.
941 0           $cmd = $hist[$i];
942 0           print $OUT $cmd, "\n";
943 0           redo CMD;
944             };
945              
946             # $sh - start a shell.
947 0 0         $cmd =~ /^$sh$/ && do {
948              
949             # Run the user's shell. If none defined, run Bourne.
950             # We resume execution when the shell terminates.
951 0   0       &system( $ENV{SHELL} || "/bin/sh" );
952 0           next CMD;
953             };
954              
955             # $sh command - start a shell and run a command in it.
956 0 0         $cmd =~ /^$sh\s*([\x00-\xff]*)/ && do {
957              
958             # XXX: using csh or tcsh destroys sigint retvals!
959             #&system($1); # use this instead
960              
961             # use the user's shell, or Bourne if none defined.
962 0   0       &system( $ENV{SHELL} || "/bin/sh", "-c", $1 );
963 0           next CMD;
964             };
965              
966 0 0         $cmd =~ /^H\b\s*\*/ && do {
967 0           @hist = @truehist = ();
968 0           print $OUT "History cleansed\n";
969 0           next CMD;
970             };
971              
972 0 0         $cmd =~ /^H\b\s*(-(\d+))?/ && do {
973              
974             # Anything other than negative numbers is ignored by
975             # the (incorrect) pattern, so this test does nothing.
976 0 0         $end = $2 ? ( $#hist - $2 ) : 0;
977              
978             # Set to the minimum if less than zero.
979 0 0         $hist = 0 if $hist < 0;
980              
981             # Start at the end of the array.
982             # Stay in while we're still above the ending value.
983             # Tick back by one each time around the loop.
984 0           for ( $i = $#hist ; $i > $end ; $i-- ) {
985              
986             # Print the command unless it has no arguments.
987 0 0         print $OUT "$i: ", $hist[$i], "\n"
988             unless $hist[$i] =~ /^.?$/;
989             }
990 0           next CMD;
991             };
992              
993             # man, perldoc, doc - show manual pages.
994 0 0         $cmd =~ /^(?:man|(?:perl)?doc)\b(?:\s+([^(]*))?$/ && do {
995 0           runman($1);
996 0           next CMD;
997             };
998              
999             # p - print (no args): print $_.
1000 0           $cmd =~ s/^p$/print {\$DB::OUT} \$_/;
1001              
1002             # p - print the given expression.
1003 0           $cmd =~ s/^p\b/print {\$DB::OUT} /;
1004              
1005             # = - set up a command alias.
1006 0 0         $cmd =~ s/^=\s*// && do {
1007 0           my @keys;
1008 0 0         if ( length $cmd == 0 ) {
    0          
1009              
1010             # No args, get current aliases.
1011 0           @keys = sort keys %alias;
1012             }
1013             elsif ( my ( $k, $v ) = ( $cmd =~ /^(\S+)\s+(\S.*)/ ) ) {
1014              
1015             # Creating a new alias. $k is alias name, $v is
1016             # alias value.
1017              
1018             # can't use $_ or kill //g state
1019 0           for my $x ( $k, $v ) {
1020              
1021             # Escape "alarm" characters.
1022 0           $x =~ s/\a/\\a/g;
1023             }
1024              
1025             # Substitute key for value, using alarm chars
1026             # as separators (which is why we escaped them in
1027             # the command).
1028 0           $alias{$k} = "s\a$k\a$v\a";
1029              
1030             # Turn off standard warn and die behavior.
1031 0           local $SIG{__DIE__};
1032 0           local $SIG{__WARN__};
1033              
1034             # Is it valid Perl?
1035 0 0         unless ( eval "sub { s\a$k\a$v\a }; 1" ) {
1036              
1037             # Nope. Bad alias. Say so and get out.
1038 0           print $OUT "Can't alias $k to $v: $@\n";
1039 0           delete $alias{$k};
1040 0           next CMD;
1041             }
1042              
1043             # We'll only list the new one.
1044 0           @keys = ($k);
1045             } ## end elsif (my ($k, $v) = ($cmd...
1046              
1047             # The argument is the alias to list.
1048             else {
1049 0           @keys = ($cmd);
1050             }
1051              
1052             # List aliases.
1053 0           for my $k (@keys) {
1054              
1055             # Messy metaquoting: Trim the substiution code off.
1056             # We use control-G as the delimiter because it's not
1057             # likely to appear in the alias.
1058 0 0         if ( ( my $v = $alias{$k} ) =~ ss\a$k\a(.*)\a$1 ) {
    0          
1059              
1060             # Print the alias.
1061 0           print $OUT "$k\t= $1\n";
1062             }
1063             elsif ( defined $alias{$k} ) {
1064              
1065             # Couldn't trim it off; just print the alias code.
1066 0           print $OUT "$k\t$alias{$k}\n";
1067             }
1068             else {
1069              
1070             # No such, dude.
1071 0           print "No alias for $k\n";
1072             }
1073             } ## end for my $k (@keys)
1074 0           next CMD;
1075             };
1076              
1077             # source - read commands from a file (or pipe!) and execute.
1078 0 0         $cmd =~ /^source\s+(.*\S)/ && do {
1079 0 0         if ( open my $fh, $1 ) {
1080              
1081             # Opened OK; stick it in the list of file handles.
1082 0           push @cmdfhs, $fh;
1083             }
1084             else {
1085              
1086             # Couldn't open it.
1087 0           &warn("Can't execute `$1': $!\n");
1088             }
1089 0           next CMD;
1090             };
1091              
1092             # save source - write commands to a file for later use
1093 0 0         $cmd =~ /^save\s*(.*)$/ && do {
1094 0   0       my $file = $1 || '.perl5dbrc'; # default?
1095 0 0         if ( open my $fh, "> $file" ) {
1096              
1097             # chomp to remove extraneous newlines from source'd files
1098 0 0         chomp( my @truelist =
1099 0           map { m/^\s*(save|source)/ ? "#$_" : $_ }
1100             @truehist );
1101 0           print $fh join( "\n", @truelist );
1102 0           print "commands saved in $file\n";
1103             }
1104             else {
1105 0           &warn("Can't save debugger commands in '$1': $!\n");
1106             }
1107 0           next CMD;
1108             };
1109              
1110             # R - restart execution.
1111             # rerun - controlled restart execution.
1112 0 0         $cmd =~ /^(R|rerun\s*(.*))$/ && do {
1113 0 0         my @args = ($1 eq 'R' ? restart() : rerun($2));
1114              
1115             # And run Perl again. We use exec() to keep the
1116             # PID stable (and that way $ini_pids is still valid).
1117 0 0         exec(@args) || print $OUT "exec failed: $!\n";
1118              
1119 0           last CMD;
1120             };
1121              
1122             # || - run command in the pager, with output to DB::OUT.
1123 0 0         $cmd =~ /^\|\|?\s*[^|]/ && do {
1124 0 0         if ( $pager =~ /^\|/ ) {
1125              
1126             # Default pager is into a pipe. Redirect I/O.
1127 0 0         open( SAVEOUT, ">&STDOUT" )
1128             || &warn("Can't save STDOUT");
1129 0 0         open( STDOUT, ">&OUT" )
1130             || &warn("Can't redirect STDOUT");
1131             } ## end if ($pager =~ /^\|/)
1132             else {
1133              
1134             # Not into a pipe. STDOUT is safe.
1135 0 0         open( SAVEOUT, ">&OUT" ) || &warn("Can't save DB::OUT");
1136             }
1137              
1138             # Fix up environment to record we have less if so.
1139 0           fix_less();
1140              
1141 0 0         unless ( $piped = open( OUT, $pager ) ) {
1142              
1143             # Couldn't open pipe to pager.
1144 0           &warn("Can't pipe output to `$pager'");
1145 0 0         if ( $pager =~ /^\|/ ) {
1146              
1147             # Redirect I/O back again.
1148 0 0         open( OUT, ">&STDOUT" ) # XXX: lost message
1149             || &warn("Can't restore DB::OUT");
1150 0 0         open( STDOUT, ">&SAVEOUT" )
1151             || &warn("Can't restore STDOUT");
1152 0           close(SAVEOUT);
1153             } ## end if ($pager =~ /^\|/)
1154             else {
1155              
1156             # Redirect I/O. STDOUT already safe.
1157 0 0         open( OUT, ">&STDOUT" ) # XXX: lost message
1158             || &warn("Can't restore DB::OUT");
1159             }
1160 0           next CMD;
1161             } ## end unless ($piped = open(OUT,...
1162              
1163             # Set up broken-pipe handler if necessary.
1164 0 0 0       $SIG{PIPE} = \&DB::catch
      0        
1165             if $pager =~ /^\|/
1166             && ( "" eq $SIG{PIPE} || "DEFAULT" eq $SIG{PIPE} );
1167              
1168             # Save current filehandle, unbuffer out, and put it back.
1169 0           $selected = select(OUT);
1170 0           $| = 1;
1171              
1172             # Don't put it back if pager was a pipe.
1173 0 0         select($selected), $selected = "" unless $cmd =~ /^\|\|/;
1174              
1175             # Trim off the pipe symbols and run the command now.
1176 0           $cmd =~ s/^\|+\s*//;
1177 0           redo PIPE;
1178             };
1179              
1180             # t - turn trace on.
1181 0           $cmd =~ s/^t\s/\$DB::trace |= 1;\n/;
1182              
1183             # s - single-step. Remember the last command was 's'.
1184 0 0         $cmd =~ s/^s\s/\$DB::single = 1;\n/ && do { $laststep = 's' };
  0            
1185              
1186             # n - single-step, but not into subs. Remember last command
1187             # was 'n'.
1188 0 0         $cmd =~ s/^n\s/\$DB::single = 2;\n/ && do { $laststep = 'n' };
  0            
1189              
1190             } # PIPE:
1191              
1192             # Make sure the flag that says "the debugger's running" is
1193             # still on, to make sure we get control again.
1194 0           $evalarg = "\$^D = \$^D | \$DB::db_stop;\n$cmd";
1195              
1196             # Run *our* eval that executes in the caller's context.
1197 0           &eval;
1198              
1199             # Turn off the one-time-dump stuff now.
1200 0 0         if ($onetimeDump) {
    0          
1201 0           $onetimeDump = undef;
1202 0           $onetimedumpDepth = undef;
1203             }
1204             elsif ( $term_pid == $$ ) {
1205 0           STDOUT->flush();
1206 0           STDERR->flush();
1207              
1208             # XXX If this is the master pid, print a newline.
1209 0           print $OUT "\n";
1210             }
1211             } ## end while (($term || &setterm...
1212              
1213              
1214             continue { # CMD:
1215              
1216             # At the end of every command:
1217 0 0         if ($piped) {
1218              
1219             # Unhook the pipe mechanism now.
1220 0 0         if ( $pager =~ /^\|/ ) {
1221              
1222             # No error from the child.
1223 0           $? = 0;
1224              
1225             # we cannot warn here: the handle is missing --tchrist
1226 0 0         close(OUT) || print SAVEOUT "\nCan't close DB::OUT\n";
1227              
1228             # most of the $? crud was coping with broken cshisms
1229             # $? is explicitly set to 0, so this never runs.
1230 0 0         if ($?) {
1231 0           print SAVEOUT "Pager `$pager' failed: ";
1232 0 0         if ( $? == -1 ) {
    0          
1233 0           print SAVEOUT "shell returned -1\n";
1234             }
1235             elsif ( $? >> 8 ) {
1236 0 0         print SAVEOUT ( $? & 127 )
    0          
1237             ? " (SIG#" . ( $? & 127 ) . ")"
1238             : "", ( $? & 128 ) ? " -- core dumped" : "", "\n";
1239             }
1240             else {
1241 0           print SAVEOUT "status ", ( $? >> 8 ), "\n";
1242             }
1243             } ## end if ($?)
1244              
1245             # Reopen filehandle for our output (if we can) and
1246             # restore STDOUT (if we can).
1247 0 0         open( OUT, ">&STDOUT" ) || &warn("Can't restore DB::OUT");
1248 0 0         open( STDOUT, ">&SAVEOUT" )
1249             || &warn("Can't restore STDOUT");
1250              
1251             # Turn off pipe exception handler if necessary.
1252 0 0         $SIG{PIPE} = "DEFAULT" if $SIG{PIPE} eq \&DB::catch;
1253              
1254             # Will stop ignoring SIGPIPE if done like nohup(1)
1255             # does SIGINT but Perl doesn't give us a choice.
1256             } ## end if ($pager =~ /^\|/)
1257             else {
1258              
1259             # Non-piped "pager". Just restore STDOUT.
1260 0 0         open( OUT, ">&SAVEOUT" ) || &warn("Can't restore DB::OUT");
1261             }
1262              
1263             # Close filehandle pager was using, restore the normal one
1264             # if necessary,
1265 0           close(SAVEOUT);
1266 0 0         select($selected), $selected = "" unless $selected eq "";
1267              
1268             # No pipes now.
1269 0           $piped = "";
1270             } ## end if ($piped)
1271             } # CMD:
1272              
1273             # No more commands? Quit.
1274 0 0         $fall_off_end = 1 unless defined $cmd; # Emulate `q' on EOF
1275              
1276             # Evaluate post-prompt commands.
1277 0           foreach $evalarg (@$post) {
1278 0           &eval;
1279             }
1280             } # if ($single || $signal)
1281              
1282             # Put the user's globals back where you found them.
1283 0           ( $@, $!, $^E, $,, $/, $\, $^W ) = @saved;
1284 0           ();
1285             } ## end sub DB
1286              
1287             }
1288              
1289             1;
1290             __END__