5c8d2727b72506d2c3f6999246d84b0722a40f0d
[p5sagit/p5-mst-13.2.git] / lib / perl5db.pl
1 package DB;
2
3 # Debugger for Perl 5.00x; perl5db.pl patch level:
4
5 $header = 'perl5db.pl patch level 0.94';
6
7 # Enhanced by ilya@math.ohio-state.edu (Ilya Zakharevich)
8 # Latest version available: ftp://ftp.math.ohio-state.edu/pub/users/ilya/perl
9
10 # modified Perl debugger, to be run from Emacs in perldb-mode
11 # Ray Lischner (uunet!mntgfx!lisch) as of 5 Nov 1990
12 # Johan Vromans -- upgrade to 4.0 pl 10
13 # Ilya Zakharevich -- patches after 5.001 (and some before ;-)
14
15 #
16 # This file is automatically included if you do perl -d.
17 # It's probably not useful to include this yourself.
18 #
19 # Perl supplies the values for @line and %sub.  It effectively inserts
20 # a &DB'DB(<linenum>); in front of every place that can have a
21 # breakpoint. Instead of a subroutine call it calls &DB::sub with
22 # $DB::sub being the called subroutine. It also inserts a BEGIN
23 # {require 'perl5db.pl'} before the first line.
24 #
25 # Note that no subroutine call is possible until &DB::sub is defined
26 # (for subroutines defined outside this file). In fact the same is
27 # true if $deep is not defined.
28 #
29 # $Log: perldb.pl,v $
30
31 #
32 # At start reads $rcfile that may set important options.  This file
33 # may define a subroutine &afterinit that will be executed after the
34 # debugger is initialized.
35 #
36 # After $rcfile is read reads environment variable PERLDB_OPTS and parses
37 # it as a rest of `O ...' line in debugger prompt.
38 #
39 # The options that can be specified only at startup:
40 # [To set in $rcfile, call &parse_options("optionName=new_value").]
41 #
42 # TTY  - the TTY to use for debugging i/o.
43 #
44 # noTTY - if set, goes in NonStop mode.  On interrupt if TTY is not set
45 # uses the value of noTTY or "/tmp/perldbtty$$" to find TTY using
46 # Term::Rendezvous.  Current variant is to have the name of TTY in this
47 # file.
48 #
49 # ReadLine - If false, dummy ReadLine is used, so you can debug
50 # ReadLine applications.
51 #
52 # NonStop - if true, no i/o is performed until interrupt.
53 #
54 # LineInfo - file or pipe to print line number info to.  If it is a
55 # pipe, a short "emacs like" message is used.
56 #
57 # Example $rcfile: (delete leading hashes!)
58 #
59 # &parse_options("NonStop=1 LineInfo=db.out");
60 # sub afterinit { $trace = 1; }
61 #
62 # The script will run without human intervention, putting trace
63 # information into db.out.  (If you interrupt it, you would better
64 # reset LineInfo to something "interactive"!)
65 #
66
67 # Needed for the statement after exec():
68
69 BEGIN { $ini_warn = $^W; $^W = 0 } # Switch compilation warnings off until another BEGIN.
70 local($^W) = 0;                 # Switch run-time warnings off during init.
71 warn (                  # Do not ;-)
72       $dumpvar::hashDepth,     
73       $dumpvar::arrayDepth,    
74       $dumpvar::dumpDBFiles,   
75       $dumpvar::dumpPackages,  
76       $dumpvar::quoteHighBit,  
77       $dumpvar::printUndef,    
78       $dumpvar::globPrint,     
79       $readline::Tk_toloop,    
80       $dumpvar::usageOnly,
81       @ARGS,
82       $Carp::CarpLevel,
83       $panic,
84       $first_time,
85      ) if 0;
86
87 # Command-line + PERLLIB:
88 @ini_INC = @INC;
89
90 # $prevwarn = $prevdie = $prevbus = $prevsegv = ''; # Does not help?!
91
92 $trace = $signal = $single = 0; # Uninitialized warning suppression
93                                 # (local $^W cannot help - other packages!).
94 @stack = (0);
95
96 $option{PrintRet} = 1;
97
98 @options     = qw(hashDepth arrayDepth DumpDBFiles DumpPackages 
99                   compactDump veryCompact quote HighBit undefPrint
100                   globPrint PrintRet UsageOnly frame
101                   TTY noTTY ReadLine NonStop LineInfo
102                   recallCommand ShellBang pager tkRunning
103                   signalLevel warnLevel dieLevel);
104
105 %optionVars    = (
106                  hashDepth      => \$dumpvar::hashDepth,
107                  arrayDepth     => \$dumpvar::arrayDepth,
108                  DumpDBFiles    => \$dumpvar::dumpDBFiles,
109                  DumpPackages   => \$dumpvar::dumpPackages,
110                  HighBit        => \$dumpvar::quoteHighBit,
111                  undefPrint     => \$dumpvar::printUndef,
112                  globPrint      => \$dumpvar::globPrint,
113                  tkRunning      => \$readline::Tk_toloop,
114                  UsageOnly      => \$dumpvar::usageOnly,     
115                   frame           => \$frame,
116 );
117
118 %optionAction  = (
119                   compactDump   => \&dumpvar::compactDump,
120                   veryCompact   => \&dumpvar::veryCompact,
121                   quote         => \&dumpvar::quote,
122                   TTY           => \&TTY,
123                   noTTY         => \&noTTY,
124                   ReadLine      => \&ReadLine,
125                   NonStop       => \&NonStop,
126                   LineInfo      => \&LineInfo,
127                   recallCommand => \&recallCommand,
128                   ShellBang     => \&shellBang,
129                   pager         => \&pager,
130                   signalLevel   => \&signalLevel,
131                   warnLevel     => \&warnLevel,
132                   dieLevel      => \&dieLevel,
133                  );
134
135 %optionRequire = (
136                   compactDump   => 'dumpvar.pl',
137                   veryCompact   => 'dumpvar.pl',
138                   quote         => 'dumpvar.pl',
139                  );
140
141 # These guys may be defined in $ENV{PERL5DB} :
142 $rl = 1 unless defined $rl;
143 warnLevel($warnLevel);
144 dieLevel($dieLevel);
145 signalLevel($signalLevel);
146 &pager(defined($ENV{PAGER}) ? $ENV{PAGER} : "|more") unless defined $pager;
147 &recallCommand("!") unless defined $prc;
148 &shellBang("!") unless defined $psh;
149
150 if (-e "/dev/tty") {
151   $rcfile=".perldb";
152 } else {
153   $rcfile="perldb.ini";
154 }
155
156 if (-f $rcfile) {
157     do "./$rcfile";
158 } elsif (defined $ENV{LOGDIR} and -f "$ENV{LOGDIR}/$rcfile") {
159     do "$ENV{LOGDIR}/$rcfile";
160 } elsif (defined $ENV{HOME} and -f "$ENV{HOME}/$rcfile") {
161     do "$ENV{HOME}/$rcfile";
162 }
163
164 if (defined $ENV{PERLDB_OPTS}) {
165   parse_options($ENV{PERLDB_OPTS});
166 }
167
168 if (exists $ENV{PERLDB_RESTART}) {
169   delete $ENV{PERLDB_RESTART};
170   # $restart = 1;
171   @hist = get_list('PERLDB_HIST');
172   my @visited = get_list("PERLDB_VISITED");
173   for (0 .. $#visited) {
174     %{$postponed{$visited[$_]}} = get_list("PERLDB_FILE_$_");
175   }
176   my %opt = get_list("PERLDB_OPT");
177   my ($opt,$val);
178   while (($opt,$val) = each %opt) {
179     $val =~ s/[\\\']/\\$1/g;
180     parse_options("$opt'$val'");
181   }
182   @INC = get_list("PERLDB_INC");
183   @ini_INC = @INC;
184 }
185
186 if ($notty) {
187   $runnonstop = 1;
188 } else {
189   # Is Perl being run from Emacs?
190   $emacs = ((defined $main::ARGV[0]) and ($main::ARGV[0] eq '-emacs'));
191   $rl = 0, shift(@main::ARGV) if $emacs;
192
193   #require Term::ReadLine;
194
195   if (-e "/dev/tty") {
196     $console = "/dev/tty";
197   } elsif (-e "con") {
198     $console = "con";
199   } else {
200     $console = "sys\$command";
201   }
202
203   # Around a bug:
204   if (defined $ENV{OS2_SHELL} and $emacs) { # In OS/2
205     $console = undef;
206   }
207
208   $console = $tty if defined $tty;
209
210   if (defined $console) {
211     open(IN,"+<$console") || open(IN,"<$console") || open(IN,"<&STDIN");
212     open(OUT,"+>$console") || open(OUT,">$console") || open(OUT,">&STDERR")
213       || open(OUT,">&STDOUT");  # so we don't dongle stdout
214   } else {
215     open(IN,"<&STDIN");
216     open(OUT,">&STDERR") || open(OUT,">&STDOUT"); # so we don't dongle stdout
217     $console = 'STDIN/OUT';
218   }
219   # so open("|more") can read from STDOUT and so we don't dingle stdin
220   $IN = \*IN;
221
222   $OUT = \*OUT;
223   select($OUT);
224   $| = 1;                       # for DB::OUT
225   select(STDOUT);
226
227   $LINEINFO = $OUT unless defined $LINEINFO;
228   $lineinfo = $console unless defined $lineinfo;
229
230   $| = 1;                       # for real STDOUT
231
232   $header =~ s/.Header: ([^,]+),v(\s+\S+\s+\S+).*$/$1$2/;
233   unless ($runnonstop) {
234     print $OUT "\nLoading DB routines from $header\n";
235     print $OUT ("Emacs support ",
236                 $emacs ? "enabled" : "available",
237                 ".\n");
238     print $OUT "\nEnter h or `h h' for help.\n\n";
239   }
240 }
241
242 @ARGS = @ARGV;
243 for (@args) {
244     s/\'/\\\'/g;
245     s/(.*)/'$1'/ unless /^-?[\d.]+$/;
246 }
247
248 if (defined &afterinit) {       # May be defined in $rcfile
249   &afterinit();
250 }
251
252 ############################################################ Subroutines
253
254 sub DB {
255     unless ($first_time++) {    # Do when-running init
256       if ($runnonstop) {                # Disable until signal
257         for ($i=0; $i <= $#stack; ) {
258             $stack[$i++] &= ~1;
259         }
260         $single = 0;
261         return;
262       }
263       # Define a subroutine in which we will stop
264 #       eval <<'EOE';
265 # sub at_end::db {"Debuggee terminating";}
266 # END {
267 #   $DB::step = 1; 
268 #   print $OUT "Debuggee terminating.\n"; 
269 #   &at_end::db;}
270 # EOE
271     }
272     &save;
273     if ($doret) {
274         $doret = 0;
275         if ($option{PrintRet}) {
276             print $OUT "$retctx context return from $lastsub:", 
277               ($retctx eq 'list') ? "\n" : " " ;
278             dumpit( ($retctx eq 'list') ? \@ret : $ret );
279         }
280     }
281     ($package, $filename, $line) = caller;
282     $filename_ini = $filename;
283     $usercontext = '($@, $!, $,, $/, $\, $^W) = @saved;' .
284       "package $package;";      # this won't let them modify, alas
285     local(*dbline) = "::_<$filename";
286     install_breakpoints($filename) unless $visited{$filename}++;
287     $max = $#dbline;
288     if (($stop,$action) = split(/\0/,$dbline{$line})) {
289         if ($stop eq '1') {
290             $signal |= 1;
291         } elsif ($stop) {
292             $evalarg = "\$DB::signal |= do {$stop;}"; &eval;
293             $dbline{$line} =~ s/;9($|\0)/$1/;
294         }
295     }
296     if ($single || $trace || $signal) {
297         $term || &setterm;
298         if ($emacs) {
299             $position = "\032\032$filename:$line:0\n";
300             print $LINEINFO $position;
301         } else {
302             $sub =~ s/\'/::/;
303             $prefix = $sub =~ /::/ ? "" : "${'package'}::";
304             $prefix .= "$sub($filename:";
305             $after = ($dbline[$line] =~ /\n$/ ? '' : "\n");
306             if (length($prefix) > 30) {
307                 $position = "$prefix$line):\n$line:\t$dbline[$line]$after";
308                 print $LINEINFO $position;
309                 $prefix = "";
310                 $infix = ":\t";
311             } else {
312                 $infix = "):\t";
313                 $position = "$prefix$line$infix$dbline[$line]$after";
314                 print $LINEINFO $position;
315             }
316             for ($i = $line + 1; $i <= $max && $dbline[$i] == 0; ++$i) { #{ vi
317                 last if $dbline[$i] =~ /^\s*[\;\}\#\n]/;
318                 $after = ($dbline[$i] =~ /\n$/ ? '' : "\n");
319                 $incr_pos = "$prefix$i$infix$dbline[$i]$after";
320                 print $LINEINFO $incr_pos;
321                 $position .= $incr_pos;
322             }
323         }
324     }
325     $evalarg = $action, &eval if $action;
326     if ($single || $signal) {
327         local $level = $level + 1;
328         $evalarg = $pre, &eval if $pre;
329         print $OUT $#stack . " levels deep in subroutine calls!\n"
330           if $single & 4;
331         $start = $line;
332       CMD:
333         while (($term || &setterm),
334                defined ($cmd=&readline("  DB" . ('<' x $level) .
335                                        ($#hist+1) . ('>' x $level) .
336                                        " "))) {
337             #{                  # <-- Do we know what this brace is for?
338                 $single = 0;
339                 $signal = 0;
340                 $cmd =~ s/\\$/\n/ && do {
341                     $cmd .= &readline("  cont: ");
342                     redo CMD;
343                 };
344                 $cmd =~ /^q$/ && exit 0;
345                 $cmd =~ /^$/ && ($cmd = $laststep);
346                 push(@hist,$cmd) if length($cmd) > 1;
347               PIPE: {
348                     ($i) = split(/\s+/,$cmd);
349                     eval "\$cmd =~ $alias{$i}", print $OUT $@ if $alias{$i};
350                     $cmd =~ /^h$/ && do {
351                         print $OUT $help;
352                         next CMD; };
353                     $cmd =~ /^h\s+h$/ && do {
354                         print $OUT $summary;
355                         next CMD; };
356                     $cmd =~ /^h\s+(\S)$/ && do {
357                         my $asked = "\Q$1";
358                         if ($help =~ /^($asked([\s\S]*?)\n)(\Z|[^\s$asked])/m) {
359                             print $OUT $1;
360                         } else {
361                             print $OUT "`$asked' is not a debugger command.\n";
362                         }
363                         next CMD; };
364                     $cmd =~ /^t$/ && do {
365                         $trace = !$trace;
366                         print $OUT "Trace = ".($trace?"on":"off")."\n";
367                         next CMD; };
368                     $cmd =~ /^S(\s+(!)?(.+))?$/ && do {
369                         $Srev = defined $2; $Spatt = $3; $Snocheck = ! defined $1;
370                         foreach $subname (sort(keys %sub)) {
371                             if ($Snocheck or $Srev^($subname =~ /$Spatt/)) {
372                                 print $OUT $subname,"\n";
373                             }
374                         }
375                         next CMD; };
376                     $cmd =~ s/^X\b/V $package/;
377                     $cmd =~ /^V$/ && do {
378                         $cmd = "V $package"; };
379                     $cmd =~ /^V\b\s*(\S+)\s*(.*)/ && do {
380                         local ($savout) = select($OUT);
381                         $packname = $1;
382                         @vars = split(' ',$2);
383                         do 'dumpvar.pl' unless defined &main::dumpvar;
384                         if (defined &main::dumpvar) {
385                             local $frame = 0;
386                             &main::dumpvar($packname,@vars);
387                         } else {
388                             print $OUT "dumpvar.pl not available.\n";
389                         }
390                         select ($savout);
391                         next CMD; };
392                     $cmd =~ s/^x\b/ / && do { # So that will be evaled
393                         $onetimeDump = 1; };
394                     $cmd =~ /^f\b\s*(.*)/ && do {
395                         $file = $1;
396                         if (!$file) {
397                             print $OUT "The old f command is now the r command.\n";
398                             print $OUT "The new f command switches filenames.\n";
399                             next CMD;
400                         }
401                         if (!defined $main::{'_<' . $file}) {
402                             if (($try) = grep(m#^_<.*$file#, keys %main::)) {{
403                                               $file = substr($try,2);
404                                               print "\n$file:\n";
405                                           }}
406                         }
407                         if (!defined $main::{'_<' . $file}) {
408                             print $OUT "There's no code here matching $file.\n";
409                             next CMD;
410                         } elsif ($file ne $filename) {
411                             *dbline = "::_<$file";
412                             $visited{$file}++;
413                             $max = $#dbline;
414                             $filename = $file;
415                             $start = 1;
416                             $cmd = "l";
417                         } };
418                     $cmd =~ /^l\b\s*([\':A-Za-z_][\':\w]*)/ && do {
419                         $subname = $1;
420                         $subname =~ s/\'/::/;
421                         $subname = "main::".$subname unless $subname =~ /::/;
422                         $subname = "main".$subname if substr($subname,0,2) eq "::";
423                         @pieces = split(/:/,$sub{$subname});
424                         $subrange = pop @pieces;
425                         $file = join(':', @pieces);
426                         if ($file ne $filename) {
427                             *dbline = "::_<$file";
428                             $visited{$file}++;
429                             $max = $#dbline;
430                             $filename = $file;
431                         }
432                         if ($subrange) {
433                             if (eval($subrange) < -$window) {
434                                 $subrange =~ s/-.*/+/;
435                             }
436                             $cmd = "l $subrange";
437                         } else {
438                             print $OUT "Subroutine $subname not found.\n";
439                             next CMD;
440                         } };
441                     $cmd =~ /^\.$/ && do {
442                         $start = $line;
443                         $filename = $filename_ini;
444                         *dbline = "::_<$filename";
445                         $max = $#dbline;
446                         print $LINEINFO $position;
447                         next CMD };
448                     $cmd =~ /^w\b\s*(\d*)$/ && do {
449                         $incr = $window - 1;
450                         $start = $1 if $1;
451                         $start -= $preview;
452                         #print $OUT 'l ' . $start . '-' . ($start + $incr);
453                         $cmd = 'l ' . $start . '-' . ($start + $incr); };
454                     $cmd =~ /^-$/ && do {
455                         $incr = $window - 1;
456                         $cmd = 'l ' . ($start-$window*2) . '+'; };
457                     $cmd =~ /^l$/ && do {
458                         $incr = $window - 1;
459                         $cmd = 'l ' . $start . '-' . ($start + $incr); };
460                     $cmd =~ /^l\b\s*(\d*)\+(\d*)$/ && do {
461                         $start = $1 if $1;
462                         $incr = $2;
463                         $incr = $window - 1 unless $incr;
464                         $cmd = 'l ' . $start . '-' . ($start + $incr); };
465                     $cmd =~ /^l\b\s*((-?[\d\$\.]+)([-,]([\d\$\.]+))?)?/ && do {
466                         $end = (!defined $2) ? $max : ($4 ? $4 : $2);
467                         $end = $max if $end > $max;
468                         $i = $2;
469                         $i = $line if $i eq '.';
470                         $i = 1 if $i < 1;
471                         if ($emacs) {
472                             print $OUT "\032\032$filename:$i:0\n";
473                             $i = $end;
474                         } else {
475                             for (; $i <= $end; $i++) {
476                                 ($stop,$action) = split(/\0/, $dbline{$i});
477                                 $arrow = ($i==$line 
478                                           and $filename eq $filename_ini) 
479                                   ?  '==>' 
480                                     : ':' ;
481                                 $arrow .= 'b' if $stop;
482                                 $arrow .= 'a' if $action;
483                                 print $OUT "$i$arrow\t", $dbline[$i];
484                                 last if $signal;
485                             }
486                         }
487                         $start = $i; # remember in case they want more
488                         $start = $max if $start > $max;
489                         next CMD; };
490                     $cmd =~ /^D$/ && do {
491                         print $OUT "Deleting all breakpoints...\n";
492                         for ($i = 1; $i <= $max ; $i++) {
493                             if (defined $dbline{$i}) {
494                                 $dbline{$i} =~ s/^[^\0]+//;
495                                 if ($dbline{$i} =~ s/^\0?$//) {
496                                     delete $dbline{$i};
497                                 }
498                             }
499                         }
500                         next CMD; };
501                     $cmd =~ /^L$/ && do {
502                         for ($i = 1; $i <= $max; $i++) {
503                             if (defined $dbline{$i}) {
504                                 print $OUT "$i:\t", $dbline[$i];
505                                 ($stop,$action) = split(/\0/, $dbline{$i});
506                                 print $OUT "  break if (", $stop, ")\n"
507                                   if $stop;
508                                 print $OUT "  action:  ", $action, "\n"
509                                   if $action;
510                                 last if $signal;
511                             }
512                         }
513                         next CMD; };
514                     $cmd =~ /^b\b\s*([':A-Za-z_][':\w]*)\s*(.*)/ && do {
515                         $subname = $1;
516                         $cond = $2 || '1';
517                         $subname =~ s/\'/::/;
518                         $subname = "${'package'}::" . $subname
519                           unless $subname =~ /::/;
520                         $subname = "main".$subname if substr($subname,0,2) eq "::";
521                         # Filename below can contain ':'
522                         ($file,$i) = ($sub{$subname} =~ /^(.*):(.*)$/);
523                         $i += 0;
524                         if ($i) {
525                             $filename = $file;
526                             *dbline = "::_<$filename";
527                             $visited{$filename}++;
528                             $max = $#dbline;
529                             ++$i while $dbline[$i] == 0 && $i < $max;
530                             $dbline{$i} =~ s/^[^\0]*/$cond/;
531                         } else {
532                             print $OUT "Subroutine $subname not found.\n";
533                         }
534                         next CMD; };
535                     $cmd =~ /^b\b\s*(\d*)\s*(.*)/ && do {
536                         $i = ($1?$1:$line);
537                         $cond = $2 || '1';
538                         if ($dbline[$i] == 0) {
539                             print $OUT "Line $i not breakable.\n";
540                         } else {
541                             $dbline{$i} =~ s/^[^\0]*/$cond/;
542                         }
543                         next CMD; };
544                     $cmd =~ /^d\b\s*(\d+)?/ && do {
545                         $i = ($1?$1:$line);
546                         $dbline{$i} =~ s/^[^\0]*//;
547                         delete $dbline{$i} if $dbline{$i} eq '';
548                         next CMD; };
549                     $cmd =~ /^A$/ && do {
550                         for ($i = 1; $i <= $max ; $i++) {
551                             if (defined $dbline{$i}) {
552                                 $dbline{$i} =~ s/\0[^\0]*//;
553                                 delete $dbline{$i} if $dbline{$i} eq '';
554                             }
555                         }
556                         next CMD; };
557                     $cmd =~ /^O\s*$/ && do {
558                         for (@options) {
559                             &dump_option($_);
560                         }
561                         next CMD; };
562                     $cmd =~ /^O\s*(\S.*)/ && do {
563                         parse_options($1);
564                         next CMD; };
565                     $cmd =~ /^<\s*(.*)/ && do {
566                         $pre = action($1);
567                         next CMD; };
568                     $cmd =~ /^>\s*(.*)/ && do {
569                         $post = action($1);
570                         next CMD; };
571                     $cmd =~ /^a\b\s*(\d+)(\s+(.*))?/ && do {
572                         $i = $1; $j = $3;
573                         if ($dbline[$i] == 0) {
574                             print $OUT "Line $i may not have an action.\n";
575                         } else {
576                             $dbline{$i} =~ s/\0[^\0]*//;
577                             $dbline{$i} .= "\0" . action($j);
578                         }
579                         next CMD; };
580                     $cmd =~ /^n$/ && do {
581                         $single = 2;
582                         $laststep = $cmd;
583                         last CMD; };
584                     $cmd =~ /^s$/ && do {
585                         $single = 1;
586                         $laststep = $cmd;
587                         last CMD; };
588                     $cmd =~ /^c\b\s*([\w:]*)\s*$/ && do {
589                         $i = $1;
590                         if ($i =~ /\D/) { # subroutine name
591                             ($file,$i) = ($sub{$i} =~ /^(.*):(.*)$/);
592                             $i += 0;
593                             if ($i) {
594                                 $filename = $file;
595                                 *dbline = "::_<$filename";
596                                 $visited{$filename}++;
597                                 $max = $#dbline;
598                                 ++$i while $dbline[$i] == 0 && $i < $max;
599                             } else {
600                                 print $OUT "Subroutine $subname not found.\n";
601                                 next CMD; 
602                             }
603                         }
604                         if ($i) {
605                             if ($dbline[$i] == 0) {
606                                 print $OUT "Line $i not breakable.\n";
607                                 next CMD;
608                             }
609                             $dbline{$i} =~ s/($|\0)/;9$1/; # add one-time-only b.p.
610                         }
611                         for ($i=0; $i <= $#stack; ) {
612                             $stack[$i++] &= ~1;
613                         }
614                         last CMD; };
615                     $cmd =~ /^r$/ && do {
616                         $stack[$#stack] |= 1;
617                         $doret = 1;
618                         last CMD; };
619                     $cmd =~ /^R$/ && do {
620                         print $OUT "Warning: a lot of settings and command-line options may be lost!\n";
621                         my (@script, @flags, $cl);
622                         push @flags, '-w' if $ini_warn;
623                         # Put all the old includes at the start to get
624                         # the same debugger.
625                         for (@ini_INC) {
626                           push @flags, '-I', $_;
627                         }
628                         # Arrange for setting the old INC:
629                         set_list("PERLDB_INC", @ini_INC);
630                         if ($0 eq '-e') {
631                           for (1..$#{'::_<-e'}) { # The first line is PERL5DB
632                             chomp ($cl =  $ {'::_<-e'}[$_]);
633                             push @script, '-e', $cl;
634                           }
635                         } else {
636                           @script = $0;
637                         }
638                         set_list("PERLDB_HIST", 
639                                  $term->Features->{getHistory} 
640                                  ? $term->GetHistory : @hist);
641                         my @visited = keys %visited;
642                         set_list("PERLDB_VISITED", @visited);
643                         set_list("PERLDB_OPT", %option);
644                         for (0 .. $#visited) {
645                           *dbline = "::_<$visited[$_]";
646                           set_list("PERLDB_FILE_$_", %dbline);
647                         }
648                         $ENV{PERLDB_RESTART} = 1;
649                         #print "$^X, '-d', @flags, @script, ($emacs ? '-emacs' : ()), @ARGS";
650                         exec $^X, '-d', @flags, @script, ($emacs ? '-emacs' : ()), @ARGS;
651                         print $OUT "exec failed: $!\n";
652                         last CMD; };
653                     $cmd =~ /^T$/ && do {
654                         local($p,$f,$l,$s,$h,$a,$e,$r,@a,@sub);
655                         for ($i = 1; 
656                              ($p,$f,$l,$s,$h,$w,$e,$r) = caller($i); 
657                              $i++) {
658                             @a = ();
659                             for $arg (@args) {
660                                 $_ = "$arg";
661                                 s/([\'\\])/\\$1/g;
662                                 s/([^\0]*)/'$1'/
663                                   unless /^(?: -?[\d.]+ | \*[\w:]* )$/x;
664                                 s/([\200-\377])/sprintf("M-%c",ord($1)&0177)/eg;
665                                 s/([\0-\37\177])/sprintf("^%c",ord($1)^64)/eg;
666                                 push(@a, $_);
667                             }
668                             $w = $w ? '@ = ' : '$ = ';
669                             $a = $h ? '(' . join(', ', @a) . ')' : '';
670                             $e =~ s/\n\s*\;\s*\Z// if $e;
671                             $e =~ s/[\\\']/\\$1/g if $e;
672                             if ($r) {
673                               $s = "require '$e'";
674                             } elsif (defined $r) {
675                               $s = "eval '$e'";
676                             } elsif ($s eq '(eval)') {
677                               $s = "eval {...}";
678                             }
679                             $f = "file `$f'" unless $f eq '-e';
680                             push(@sub, "$w$s$a called from $f line $l\n");
681                             last if $signal;
682                         }
683                         for ($i=0; $i <= $#sub; $i++) {
684                             last if $signal;
685                             print $OUT $sub[$i];
686                         }
687                         next CMD; };
688                     $cmd =~ /^\/(.*)$/ && do {
689                         $inpat = $1;
690                         $inpat =~ s:([^\\])/$:$1:;
691                         if ($inpat ne "") {
692                             eval '$inpat =~ m'."\a$inpat\a";    
693                             if ($@ ne "") {
694                                 print $OUT "$@";
695                                 next CMD;
696                             }
697                             $pat = $inpat;
698                         }
699                         $end = $start;
700                         eval '
701                             for (;;) {
702                                 ++$start;
703                                 $start = 1 if ($start > $max);
704                                 last if ($start == $end);
705                                 if ($dbline[$start] =~ m' . "\a$pat\a" . 'i) {
706                                     if ($emacs) {
707                                         print $OUT "\032\032$filename:$start:0\n";
708                                     } else {
709                                         print $OUT "$start:\t", $dbline[$start], "\n";
710                                     }
711                                     last;
712                                 }
713                             } ';
714                         print $OUT "/$pat/: not found\n" if ($start == $end);
715                         next CMD; };
716                     $cmd =~ /^\?(.*)$/ && do {
717                         $inpat = $1;
718                         $inpat =~ s:([^\\])\?$:$1:;
719                         if ($inpat ne "") {
720                             eval '$inpat =~ m'."\a$inpat\a";    
721                             if ($@ ne "") {
722                                 print $OUT "$@";
723                                 next CMD;
724                             }
725                             $pat = $inpat;
726                         }
727                         $end = $start;
728                         eval '
729                             for (;;) {
730                                 --$start;
731                                 $start = $max if ($start <= 0);
732                                 last if ($start == $end);
733                                 if ($dbline[$start] =~ m' . "\a$pat\a" . 'i) {
734                                     if ($emacs) {
735                                         print $OUT "\032\032$filename:$start:0\n";
736                                     } else {
737                                         print $OUT "$start:\t", $dbline[$start], "\n";
738                                     }
739                                     last;
740                                 }
741                             } ';
742                         print $OUT "?$pat?: not found\n" if ($start == $end);
743                         next CMD; };
744                     $cmd =~ /^$rc+\s*(-)?(\d+)?$/ && do {
745                         pop(@hist) if length($cmd) > 1;
746                         $i = $1 ? ($#hist-($2?$2:1)) : ($2?$2:$#hist);
747                         $cmd = $hist[$i] . "\n";
748                         print $OUT $cmd;
749                         redo CMD; };
750                     $cmd =~ /^$sh$sh\s*/ && do {
751                         &system($');
752                         next CMD; };
753                     $cmd =~ /^$rc([^$rc].*)$/ && do {
754                         $pat = "^$1";
755                         pop(@hist) if length($cmd) > 1;
756                         for ($i = $#hist; $i; --$i) {
757                             last if $hist[$i] =~ /$pat/;
758                         }
759                         if (!$i) {
760                             print $OUT "No such command!\n\n";
761                             next CMD;
762                         }
763                         $cmd = $hist[$i] . "\n";
764                         print $OUT $cmd;
765                         redo CMD; };
766                     $cmd =~ /^$sh$/ && do {
767                         &system($ENV{SHELL}||"/bin/sh");
768                         next CMD; };
769                     $cmd =~ /^$sh\s*/ && do {
770                         &system($ENV{SHELL}||"/bin/sh","-c",$');
771                         next CMD; };
772                     $cmd =~ /^H\b\s*(-(\d+))?/ && do {
773                         $end = $2?($#hist-$2):0;
774                         $hist = 0 if $hist < 0;
775                         for ($i=$#hist; $i>$end; $i--) {
776                             print $OUT "$i: ",$hist[$i],"\n"
777                               unless $hist[$i] =~ /^.?$/;
778                         };
779                         next CMD; };
780                     $cmd =~ s/^p$/print \$DB::OUT \$_/;
781                     $cmd =~ s/^p\b/print \$DB::OUT /;
782                     $cmd =~ /^=/ && do {
783                         if (local($k,$v) = ($cmd =~ /^=\s*(\S+)\s+(.*)/)) {
784                             $alias{$k}="s~$k~$v~";
785                             print $OUT "$k = $v\n";
786                         } elsif ($cmd =~ /^=\s*$/) {
787                             foreach $k (sort keys(%alias)) {
788                                 if (($v = $alias{$k}) =~ s~^s\~$k\~(.*)\~$~$1~) {
789                                     print $OUT "$k = $v\n";
790                                 } else {
791                                     print $OUT "$k\t$alias{$k}\n";
792                                 };
793                             };
794                         };
795                         next CMD; };
796                     $cmd =~ /^\|\|?\s*[^|]/ && do {
797                         if ($pager =~ /^\|/) {
798                             open(SAVEOUT,">&STDOUT") || &warn("Can't save STDOUT");
799                             open(STDOUT,">&OUT") || &warn("Can't redirect STDOUT");
800                         } else {
801                             open(SAVEOUT,">&OUT") || &warn("Can't save DB::OUT");
802                         }
803                         unless ($piped=open(OUT,$pager)) {
804                             &warn("Can't pipe output to `$pager'");
805                             if ($pager =~ /^\|/) {
806                                 open(OUT,">&STDOUT") || &warn("Can't restore DB::OUT");
807                                 open(STDOUT,">&SAVEOUT")
808                                   || &warn("Can't restore STDOUT");
809                                 close(SAVEOUT);
810                             } else {
811                                 open(OUT,">&STDOUT") || &warn("Can't restore DB::OUT");
812                             }
813                             next CMD;
814                         }
815                         $SIG{PIPE}= "DB::catch" if $pager =~ /^\|/
816                           && "" eq $SIG{PIPE}  ||  "DEFAULT" eq $SIG{PIPE};
817                         $selected= select(OUT);
818                         $|= 1;
819                         select( $selected ), $selected= "" unless $cmd =~ /^\|\|/;
820                         $cmd =~ s/^\|+\s*//;
821                         redo PIPE; };
822                     # XXX Local variants do not work!
823                     $cmd =~ s/^t\s/\$DB::trace = 1;\n/;
824                     $cmd =~ s/^s\s/\$DB::single = 1;\n/ && do {$laststep = 's'};
825                     $cmd =~ s/^n\s/\$DB::single = 2;\n/ && do {$laststep = 'n'};
826                 }               # PIPE:
827             #}                  # <-- Do we know what this brace is for?
828             $evalarg = "\$^D = \$^D | \$DB::db_stop;\n$cmd"; &eval;
829             if ($onetimeDump) {
830                 $onetimeDump = undef;
831             } else {
832                 print $OUT "\n";
833             }
834         } continue {            # CMD:
835             if ($piped) {
836                 if ($pager =~ /^\|/) {
837                     $?= 0;  close(OUT) || &warn("Can't close DB::OUT");
838                     &warn( "Pager `$pager' failed: ",
839                           ($?>>8) > 128 ? ($?>>8)-256 : ($?>>8),
840                           ( $? & 128 ) ? " (core dumped)" : "",
841                           ( $? & 127 ) ? " (SIG ".($?&127).")" : "", "\n" ) if $?;
842                     open(OUT,">&STDOUT") || &warn("Can't restore DB::OUT");
843                     open(STDOUT,">&SAVEOUT") || &warn("Can't restore STDOUT");
844                     $SIG{PIPE}= "DEFAULT" if $SIG{PIPE} eq "DB::catch";
845                     # Will stop ignoring SIGPIPE if done like nohup(1)
846                     # does SIGINT but Perl doesn't give us a choice.
847                 } else {
848                     open(OUT,">&SAVEOUT") || &warn("Can't restore DB::OUT");
849                 }
850                 close(SAVEOUT);
851                 select($selected), $selected= "" unless $selected eq "";
852                 $piped= "";
853             }
854         }                       # CMD:
855         if ($post) {
856             $evalarg = $post; &eval;
857         }
858     }                           # if ($single || $signal)
859     ($@, $!, $,, $/, $\, $^W) = @saved;
860     ();
861 }
862
863 # The following code may be executed now:
864 # BEGIN {warn 4}
865
866 sub sub {
867     print $LINEINFO ' ' x $#stack, "entering $sub\n" if $frame;
868     push(@stack, $single);
869     $single &= 1;
870     $single |= 4 if $#stack == $deep;
871     if (wantarray) {
872         @ret = &$sub;
873         $single |= pop(@stack);
874         $retctx = "list";
875         $lastsub = $sub;
876 print $LINEINFO ' ' x $#stack, "exited $sub\n" if $frame;
877         @ret;
878     } else {
879         $ret = &$sub;
880         $single |= pop(@stack);
881         $retctx = "scalar";
882         $lastsub = $sub;
883 print $LINEINFO ' ' x $#stack, "exited $sub\n" if $frame;
884         $ret;
885     }
886 }
887
888 sub save {
889     @saved = ($@, $!, $,, $/, $\, $^W);
890     $, = ""; $/ = "\n"; $\ = ""; $^W = 0;
891 }
892
893 # The following takes its argument via $evalarg to preserve current @_
894
895 sub eval {
896     my @res;
897     {
898         local (@stack) = @stack; # guard against recursive debugging
899         my $otrace = $trace;
900         my $osingle = $single;
901         my $od = $^D;
902         @res = eval "$usercontext $evalarg;\n"; # '\n' for nice recursive debug
903         $trace = $otrace;
904         $single = $osingle;
905         $^D = $od;
906     }
907     my $at = $@;
908     eval "&DB::save";
909     if ($at) {
910         print $OUT $at;
911     } elsif ($onetimeDump) {
912         dumpit(\@res);
913     }
914 }
915
916 sub install_breakpoints {
917   my $filename = shift;
918   return unless exists $postponed{$filename};
919   my %break = %{$postponed{$filename}};
920   for (keys %break) {
921     my $i = $_;
922     #if (/\D/) {                        # Subroutine name
923     #} 
924     $dbline{$i} = $break{$_};   # Cannot be done before the file is around
925   }
926 }
927
928 sub dumpit {
929     local ($savout) = select($OUT);
930     do 'dumpvar.pl' unless defined &main::dumpValue;
931     if (defined &main::dumpValue) {
932         local $frame = 0;
933         &main::dumpValue(shift);
934     } else {
935         print $OUT "dumpvar.pl not available.\n";
936     }
937     select ($savout);    
938 }
939
940 sub action {
941     my $action = shift;
942     while ($action =~ s/\\$//) {
943         #print $OUT "+ ";
944         #$action .= "\n";
945         $action .= &gets;
946     }
947     $action;
948 }
949
950 sub gets {
951     local($.);
952     #<IN>;
953     &readline("cont: ");
954 }
955
956 sub system {
957     # We save, change, then restore STDIN and STDOUT to avoid fork() since
958     # many non-Unix systems can do system() but have problems with fork().
959     open(SAVEIN,"<&STDIN") || &warn("Can't save STDIN");
960     open(SAVEOUT,">&OUT") || &warn("Can't save STDOUT");
961     open(STDIN,"<&IN") || &warn("Can't redirect STDIN");
962     open(STDOUT,">&OUT") || &warn("Can't redirect STDOUT");
963     system(@_);
964     open(STDIN,"<&SAVEIN") || &warn("Can't restore STDIN");
965     open(STDOUT,">&SAVEOUT") || &warn("Can't restore STDOUT");
966     close(SAVEIN); close(SAVEOUT);
967     &warn( "(Command returned ", ($?>>8) > 128 ? ($?>>8)-256 : ($?>>8), ")",
968           ( $? & 128 ) ? " (core dumped)" : "",
969           ( $? & 127 ) ? " (SIG ".($?&127).")" : "", "\n" ) if $?;
970     $?;
971 }
972
973 sub setterm {
974     local $frame = 0;
975     eval "require Term::ReadLine;" or die $@;
976     if ($notty) {
977         if ($tty) {
978             open(IN,"<$tty") or die "Cannot open TTY `$TTY' for read: $!";
979             open(OUT,">$tty") or die "Cannot open TTY `$TTY' for write: $!";
980             $IN = \*IN;
981             $OUT = \*OUT;
982             my $sel = select($OUT);
983             $| = 1;
984             select($sel);
985         } else {
986             eval "require Term::Rendezvous;" or die $@;
987             my $rv = $ENV{PERLDB_NOTTY} || "/tmp/perldbtty$$";
988             my $term_rv = new Term::Rendezvous $rv;
989             $IN = $term_rv->IN;
990             $OUT = $term_rv->OUT;
991         }
992     }
993     if (!$rl) {
994         $term = new Term::ReadLine::Stub 'perldb', $IN, $OUT;
995     } else {
996         $term = new Term::ReadLine 'perldb', $IN, $OUT;
997
998         $readline::rl_basic_word_break_characters .= "[:" 
999           if defined $readline::rl_basic_word_break_characters 
1000             and index($readline::rl_basic_word_break_characters, ":") == -1;
1001     }
1002     $LINEINFO = $OUT unless defined $LINEINFO;
1003     $lineinfo = $console unless defined $lineinfo;
1004     $term->MinLine(2);
1005     if ($term->Features->{setHistory} and "@hist" ne "?") {
1006       $term->SetHistory(@hist);
1007     }
1008 }
1009
1010 sub readline {
1011   if (@typeahead) {
1012     my $left = @typeahead;
1013     my $got = shift @typeahead;
1014     print $OUT "auto(-$left)", shift, $got, "\n";
1015     $term->AddHistory($got) 
1016       if length($got) > 1 and defined $term->Features->{addHistory};
1017     return $got;
1018   }
1019   local $frame = 0;
1020   $term->readline(@_);
1021 }
1022
1023 sub dump_option {
1024     my ($opt, $val)= @_;
1025     if (defined $optionVars{$opt}
1026         and defined $ {$optionVars{$opt}}) {
1027         $val = $ {$optionVars{$opt}};
1028     } elsif (defined $optionAction{$opt}
1029         and defined &{$optionAction{$opt}}) {
1030         $val = &{$optionAction{$opt}}();
1031     } elsif (defined $optionAction{$opt}
1032              and not defined $option{$opt}
1033              or defined $optionVars{$opt}
1034              and not defined $ {$optionVars{$opt}}) {
1035         $val = 'N/A';
1036     } else {
1037         $val = $option{$opt};
1038     }
1039     $val =~ s/[\\\']/\\$&/g;
1040     printf $OUT "%20s = '%s'\n", $opt, $val;
1041 }
1042
1043 sub parse_options {
1044     local($_)= @_;
1045     while ($_ ne "") {
1046         s/^(\w+)(\s*$|\W)// or print($OUT "Invalid option `$_'\n"), last;
1047         my ($opt,$sep) = ($1,$2);
1048         my $val;
1049         if ("?" eq $sep) {
1050             print($OUT "Option query `$opt?' followed by non-space `$_'\n"), last
1051               if /^\S/;
1052             #&dump_option($opt);
1053         } elsif ($sep !~ /\S/) {
1054             $val = "1";
1055         } elsif ($sep eq "=") {
1056             s/^(\S*)($|\s+)//;
1057             $val = $1;
1058         } else { #{ to "let some poor schmuck bounce on the % key in B<vi>."
1059             my ($end) = "\\" . substr( ")]>}$sep", index("([<{",$sep), 1 ); #}
1060             s/^(([^\\$end]|\\[\\$end])*)$end($|\s+)// or
1061               print($OUT "Unclosed option value `$opt$sep$_'\n"), last;
1062             $val = $1;
1063             $val =~ s/\\([\\$end])/$1/g;
1064         }
1065         my ($option);
1066         my $matches =
1067           grep(  /^\Q$opt/ && ($option = $_),  @options  );
1068         $matches =  grep(  /^\Q$opt/i && ($option = $_),  @options  )
1069           unless $matches;
1070         print $OUT "Unknown option `$opt'\n" unless $matches;
1071         print $OUT "Ambiguous option `$opt'\n" if $matches > 1;
1072         $option{$option} = $val if $matches == 1 and defined $val;
1073         eval "local \$frame = 0; require '$optionRequire{$option}'"
1074           if $matches == 1 and defined $optionRequire{$option} and defined $val;
1075         $ {$optionVars{$option}} = $val 
1076           if $matches == 1
1077             and defined $optionVars{$option} and defined $val;
1078         & {$optionAction{$option}} ($val) 
1079           if $matches == 1
1080             and defined $optionAction{$option}
1081               and defined &{$optionAction{$option}} and defined $val;
1082         &dump_option($option) if $matches == 1 && $OUT ne \*STDERR; # Not $rcfile
1083         s/^\s+//;
1084     }
1085 }
1086
1087 sub set_list {
1088   my ($stem,@list) = @_;
1089   my $val;
1090   $ENV{"$ {stem}_n"} = @list;
1091   for $i (0 .. $#list) {
1092     $val = $list[$i];
1093     $val =~ s/\\/\\\\/g;
1094     $val =~ s/[\0-\37\177\200-\377]/"\\0x" . unpack('H2',$&)/eg;
1095     $ENV{"$ {stem}_$i"} = $val;
1096   }
1097 }
1098
1099 sub get_list {
1100   my $stem = shift;
1101   my @list;
1102   my $n = delete $ENV{"$ {stem}_n"};
1103   my $val;
1104   for $i (0 .. $n - 1) {
1105     $val = delete $ENV{"$ {stem}_$i"};
1106     $val =~ s/\\((\\)|0x(..))/ $2 ? $2 : pack('H2', $3) /ge;
1107     push @list, $val;
1108   }
1109   @list;
1110 }
1111
1112 sub catch {
1113     $signal = 1;
1114 }
1115
1116 sub warn {
1117     my($msg)= join("",@_);
1118     $msg .= ": $!\n" unless $msg =~ /\n$/;
1119     print $OUT $msg;
1120 }
1121
1122 sub TTY {
1123     if ($term) {
1124         &warn("Too late to set TTY!\n") if @_;
1125     } else {
1126         $tty = shift if @_;
1127     }
1128     $tty or $console;
1129 }
1130
1131 sub noTTY {
1132     if ($term) {
1133         &warn("Too late to set noTTY!\n") if @_;
1134     } else {
1135         $notty = shift if @_;
1136     }
1137     $notty;
1138 }
1139
1140 sub ReadLine {
1141     if ($term) {
1142         &warn("Too late to set ReadLine!\n") if @_;
1143     } else {
1144         $rl = shift if @_;
1145     }
1146     $rl;
1147 }
1148
1149 sub NonStop {
1150     if ($term) {
1151         &warn("Too late to set up NonStop mode!\n") if @_;
1152     } else {
1153         $runnonstop = shift if @_;
1154     }
1155     $runnonstop;
1156 }
1157
1158 sub pager {
1159     if (@_) {
1160         $pager = shift;
1161         $pager="|".$pager unless $pager =~ /^(\+?\>|\|)/;
1162     }
1163     $pager;
1164 }
1165
1166 sub shellBang {
1167     if (@_) {
1168         $sh = quotemeta shift;
1169         $sh .= "\\b" if $sh =~ /\w$/;
1170     }
1171     $psh = $sh;
1172     $psh =~ s/\\b$//;
1173     $psh =~ s/\\(.)/$1/g;
1174     &sethelp;
1175     $psh;
1176 }
1177
1178 sub recallCommand {
1179     if (@_) {
1180         $rc = quotemeta shift;
1181         $rc .= "\\b" if $rc =~ /\w$/;
1182     }
1183     $prc = $rc;
1184     $prc =~ s/\\b$//;
1185     $prc =~ s/\\(.)/$1/g;
1186     &sethelp;
1187     $prc;
1188 }
1189
1190 sub LineInfo {
1191     return $lineinfo unless @_;
1192     $lineinfo = shift;
1193     my $stream = ($lineinfo =~ /^(\+?\>|\|)/) ? $lineinfo : ">$lineinfo";
1194     $emacs = ($stream =~ /^\|/);
1195     open(LINEINFO, "$stream") || &warn("Cannot open `$stream' for write");
1196     $LINEINFO = \*LINEINFO;
1197     my $save = select($LINEINFO);
1198     $| = 1;
1199     select($save);
1200     $lineinfo;
1201 }
1202
1203 sub sethelp {
1204     $help = "
1205 T               Stack trace.
1206 s [expr]        Single step [in expr].
1207 n [expr]        Next, steps over subroutine calls [in expr].
1208 <CR>            Repeat last n or s command.
1209 r               Return from current subroutine.
1210 c [line]        Continue; optionally inserts a one-time-only breakpoint
1211                 at the specified line.
1212 l min+incr      List incr+1 lines starting at min.
1213 l min-max       List lines min through max.
1214 l line          List single line.
1215 l subname       List first window of lines from subroutine.
1216 l               List next window of lines.
1217 -               List previous window of lines.
1218 w [line]        List window around line.
1219 .               Return to the executed line.
1220 f filename      Switch to viewing filename.
1221 /pattern/       Search forwards for pattern; final / is optional.
1222 ?pattern?       Search backwards for pattern; final ? is optional.
1223 L               List all breakpoints and actions for the current file.
1224 S [[!]pattern]  List subroutine names [not] matching pattern.
1225 t               Toggle trace mode.
1226 t expr          Trace through execution of expr.
1227 b [line] [condition]
1228                 Set breakpoint; line defaults to the current execution line;
1229                 condition breaks if it evaluates to true, defaults to '1'.
1230 b subname [condition]
1231                 Set breakpoint at first line of subroutine.
1232 d [line]        Delete the breakpoint for line.
1233 D               Delete all breakpoints.
1234 a [line] command
1235                 Set an action to be done before the line is executed.
1236                 Sequence is: check for breakpoint, print line if necessary,
1237                 do action, prompt user if breakpoint or step, evaluate line.
1238 A               Delete all actions.
1239 V [pkg [vars]]  List some (default all) variables in package (default current).
1240                 Use ~pattern and !pattern for positive and negative regexps.
1241 X [vars]        Same as \"V currentpackage [vars]\".
1242 x expr          Evals expression in array context, dumps the result.
1243 O [opt[=val]] [opt\"val\"] [opt?]...
1244                 Set or query values of options.  val defaults to 1.  opt can
1245                 be abbreviated.  Several options can be listed.
1246     recallCommand, ShellBang:   chars used to recall command or spawn shell;
1247     pager:                      program for output of \"|cmd\";
1248   The following options affect what happens with V, X, and x commands:
1249     arrayDepth, hashDepth:      print only first N elements ('' for all);
1250     compactDump, veryCompact:   change style of array and hash dump;
1251     globPrint:                  whether to print contents of globs;
1252     DumpDBFiles:                dump arrays holding debugged files;
1253     DumpPackages:               dump symbol tables of packages;
1254     quote, HighBit, undefPrint: change style of string dump;
1255     tkRunning:                  run Tk while prompting (with ReadLine);
1256     signalLevel warnLevel dieLevel:     level of verbosity;
1257   Option PrintRet affects printing of return value after r command,
1258          frame    affects printing messages on entry and exit from subroutines.
1259                 During startup options are initialized from \$ENV{PERLDB_OPTS}.
1260                 You can put additional initialization options TTY, noTTY,
1261                 ReadLine, and NonStop there.
1262 < command       Define command to run before each prompt.
1263 > command       Define command to run after each prompt.
1264 $prc number     Redo a previous command (default previous command).
1265 $prc -number    Redo number'th-to-last command.
1266 $prc pattern    Redo last command that started with pattern.
1267                 See 'O recallCommand' too.
1268 $psh$psh cmd    Run cmd in a subprocess (reads from DB::IN, writes to DB::OUT)"
1269   . ( $rc eq $sh ? "" : "
1270 $psh [cmd]      Run cmd in subshell (forces \"\$SHELL -c 'cmd'\")." ) . "
1271                 See 'O shellBang' too.
1272 H -number       Display last number commands (default all).
1273 p expr          Same as \"print DB::OUT expr\" in current package.
1274 |dbcmd          Run debugger command, piping DB::OUT to current pager.
1275 ||dbcmd         Same as |dbcmd but DB::OUT is temporarilly select()ed as well.
1276 \= [alias value]        Define a command alias, or list current aliases.
1277 command         Execute as a perl statement in current package.
1278 R               Pure-man-restart of debugger, debugger state and command-line
1279                 options are lost.
1280 h [db_command]  Get help [on a specific debugger command], enter |h to page.
1281 h h             Summary of debugger commands.
1282 q or ^D         Quit.
1283
1284 ";
1285     $summary = <<"END_SUM";
1286 List/search source lines:               Control script execution:
1287   l [ln|sub]  List source code            T           Stack trace
1288   - or .      List previous/current line  s [expr]    Single step [in expr]
1289   w [line]    List around line            n [expr]    Next, steps over subs
1290   f filename  View source in file         <CR>        Repeat last n or s
1291   /pattern/   Search forward              r           Return from subroutine
1292   ?pattern?   Search backward             c [line]    Continue until line
1293 Debugger controls:                        L           List break pts & actions
1294   O [...]     Set debugger options        t [expr]    Toggle trace [trace expr]
1295   < command   Command for before prompt   b [ln] [c]  Set breakpoint
1296   > command   Command for after prompt    b sub [c]   Set breakpoint for sub
1297   $prc [N|pat]   Redo a previous command     d [line]    Delete a breakpoint
1298   H [-num]    Display last num commands   D           Delete all breakpoints
1299   = [a val]   Define/list an alias        a [ln] cmd  Do cmd before line
1300   h [db_cmd]  Get help on command         A           Delete all actions
1301   |[|]dbcmd   Send output to pager        $psh\[$psh\] syscmd Run cmd in a subprocess
1302   q or ^D     Quit                        R           Attempt a restart
1303 Data Examination:             expr     Execute perl code, also see: s,n,t expr
1304   S [[!]pat]    List subroutine names [not] matching pattern
1305   V [Pk [Vars]] List Variables in Package.  Vars can be ~pattern or !pattern.
1306   X [Vars]      Same as \"V current_package [Vars]\".
1307   x expr        Evals expression in array context, dumps the result.
1308   p expr        Print expression (uses script's current package).
1309 END_SUM
1310                                 # '); # Fix balance of Emacs parsing
1311 }
1312
1313 sub diesignal {
1314     local $frame = 0;
1315     $SIG{'ABRT'} = DEFAULT;
1316     kill 'ABRT', $$ if $panic++;
1317     print $DB::OUT "Got $_[0]!\n";      # in the case cannot continue
1318     local $SIG{__WARN__} = '';
1319     require Carp; 
1320     local $Carp::CarpLevel = 2;         # mydie + confess
1321     &warn(Carp::longmess("Signal @_"));
1322     kill 'ABRT', $$;
1323 }
1324
1325 sub dbwarn { 
1326   local $frame = 0;
1327   local $SIG{__WARN__} = '';
1328   require Carp; 
1329   #&warn("Entering dbwarn\n");
1330   my ($mysingle,$mytrace) = ($single,$trace);
1331   $single = 0; $trace = 0;
1332   my $mess = Carp::longmess(@_);
1333   ($single,$trace) = ($mysingle,$mytrace);
1334   #&warn("Warning in dbwarn\n");
1335   &warn($mess); 
1336   #&warn("Exiting dbwarn\n");
1337 }
1338
1339 sub dbdie {
1340   local $frame = 0;
1341   local $SIG{__DIE__} = '';
1342   local $SIG{__WARN__} = '';
1343   my $i = 0; my $ineval = 0; my $sub;
1344   #&warn("Entering dbdie\n");
1345   if ($dieLevel != 2) {
1346     while ((undef,undef,undef,$sub) = caller(++$i)) {
1347       $ineval = 1, last if $sub eq '(eval)';
1348     }
1349     {
1350       local $SIG{__WARN__} = \&dbwarn;
1351       &warn(@_) if $dieLevel > 2; # Ineval is false during destruction?
1352     }
1353     #&warn("dieing quietly in dbdie\n") if $ineval and $dieLevel < 2;
1354     die @_ if $ineval and $dieLevel < 2;
1355   }
1356   require Carp; 
1357   # We do not want to debug this chunk (automatic disabling works
1358   # inside DB::DB, but not in Carp).
1359   my ($mysingle,$mytrace) = ($single,$trace);
1360   $single = 0; $trace = 0;
1361   my $mess = Carp::longmess(@_);
1362   ($single,$trace) = ($mysingle,$mytrace);
1363   #&warn("dieing loudly in dbdie\n");
1364   die $mess;
1365 }
1366
1367 sub warnLevel {
1368   if (@_) {
1369     $prevwarn = $SIG{__WARN__} unless $warnLevel;
1370     $warnLevel = shift;
1371     if ($warnLevel) {
1372       $SIG{__WARN__} = 'DB::dbwarn';
1373     } else {
1374       $SIG{__WARN__} = $prevwarn;
1375     }
1376   }
1377   $warnLevel;
1378 }
1379
1380 sub dieLevel {
1381   if (@_) {
1382     $prevdie = $SIG{__DIE__} unless $dieLevel;
1383     $dieLevel = shift;
1384     if ($dieLevel) {
1385       $SIG{__DIE__} = 'DB::dbdie'; # if $dieLevel < 2;
1386       #$SIG{__DIE__} = 'DB::diehard' if $dieLevel >= 2;
1387       print $OUT "Stack dump during die enabled", 
1388         ( $dieLevel == 1 ? " outside of evals" : ""), ".\n";
1389       print $OUT "Dump printed too.\n" if $dieLevel > 2;
1390     } else {
1391       $SIG{__DIE__} = $prevdie;
1392       print $OUT "Default die handler restored.\n";
1393     }
1394   }
1395   $dieLevel;
1396 }
1397
1398 sub signalLevel {
1399   if (@_) {
1400     $prevsegv = $SIG{SEGV} unless $signalLevel;
1401     $prevbus = $SIG{BUS} unless $signalLevel;
1402     $signalLevel = shift;
1403     if ($signalLevel) {
1404       $SIG{SEGV} = 'DB::diesignal';
1405       $SIG{BUS} = 'DB::diesignal';
1406     } else {
1407       $SIG{SEGV} = $prevsegv;
1408       $SIG{BUS} = $prevbus;
1409     }
1410   }
1411   $signalLevel;
1412 }
1413
1414 # The following BEGIN is very handy if debugger goes havoc, debugging debugger?
1415
1416 BEGIN {                 # This does not compile, alas.
1417   $IN = \*STDIN;                # For bugs before DB::OUT has been opened
1418   $OUT = \*STDERR;              # For errors before DB::OUT has been opened
1419   $sh = '!';
1420   $rc = ',';
1421   @hist = ('?');
1422   $deep = 100;                  # warning if stack gets this deep
1423   $window = 10;
1424   $preview = 3;
1425   $sub = '';
1426   #$SIG{__WARN__} = "DB::dbwarn";
1427   #$SIG{__DIE__} = 'DB::dbdie';
1428   #$SIG{SEGV} = "DB::diesignal";
1429   #$SIG{BUS} = "DB::diesignal";
1430   $SIG{INT} = "DB::catch";
1431   #$SIG{FPE} = "DB::catch";
1432   #warn "SIGFPE installed";
1433   $warnLevel = 1 unless defined $warnLevel;
1434   $dieLevel = 1 unless defined $dieLevel;
1435   $signalLevel = 1 unless defined $signalLevel;
1436
1437   $db_stop = 0;                 # Compiler warning
1438   $db_stop = 1 << 30;
1439   $level = 0;                   # Level of recursive debugging
1440 }
1441
1442 BEGIN {$^W = $ini_warn;}        # Switch warnings back
1443
1444 #use Carp;                      # This did break, left for debuggin
1445
1446 1;