perl 3.0 patch #13 (combined patch)
[p5sagit/p5-mst-13.2.git] / lib / perldb.pl
CommitLineData
a687059c 1package DB;
2
03a14243 3$header = '$Header: perldb.pl,v 3.0.1.1 89/10/26 23:14:02 lwall Locked $';
a687059c 4#
5# This file is automatically included if you do perl -d.
6# It's probably not useful to include this yourself.
7#
8# Perl supplies the values for @line and %sub. It effectively inserts
9# a do DB'DB(<linenum>); in front of every place that can
10# have a breakpoint. It also inserts a do 'perldb.pl' before the first line.
11#
12# $Log: perldb.pl,v $
03a14243 13# Revision 3.0.1.1 89/10/26 23:14:02 lwall
14# patch1: RCS expanded an unintended $Header in lib/perldb.pl
15#
a687059c 16# Revision 3.0 89/10/18 15:19:46 lwall
17# 3.0 baseline
18#
19# Revision 2.0 88/06/05 00:09:45 root
20# Baseline version 2.0.
21#
22#
23
24open(IN,"/dev/tty"); # so we don't dingle stdin
25open(OUT,">/dev/tty"); # so we don't dongle stdout
26select(OUT);
27$| = 1; # for DB'OUT
28select(STDOUT);
29$| = 1; # for real STDOUT
30
03a14243 31$header =~ s/.Header: ([^,]+),v(\s+\S+\s+\S+).*$/$1$2/;
a687059c 32print OUT "\nLoading DB from $header\n\n";
33
34sub DB {
35 local($. ,$@, $!, $[, $,, $/, $\);
36 $[ = 0; $, = ""; $/ = "\n"; $\ = "";
37 ($line) = @_;
38 if ($stop[$line]) {
39 if ($stop eq '1') {
40 $signal |= 1;
41 }
42 else {
43 package main;
44 $DB'signal |= eval $DB'stop[$DB'line]; print DB'OUT $@;
45 $DB'stop[$DB'line] =~ s/;9$//;
46 }
47 }
48 if ($single || $trace || $signal) {
49 print OUT "$sub($line):\t",$line[$line];
50 for ($i = $line + 1; $i <= $max && $line[$i] == 0; ++$i) {
51 last if $line[$i] =~ /^\s*(}|#|\n)/;
52 print OUT "$sub($i):\t",$line[$i];
53 }
54 }
55 if ($action[$line]) {
56 package main;
57 eval $DB'action[$DB'line]; print DB'OUT $@;
58 }
59 if ($single || $signal) {
60 if ($pre) {
61 package main;
62 eval $DB'pre; print DB'OUT $@;
63 }
64 print OUT $#stack . " levels deep in subroutine calls!\n"
65 if $single & 4;
66 $start = $line;
67 while ((print OUT " DB<", $#hist+1, "> "), $cmd=<IN>) {
68 $single = 0;
69 $signal = 0;
70 $cmd eq '' && exit 0;
71 chop($cmd);
72 $cmd =~ /^q$/ && exit 0;
73 $cmd =~ /^$/ && ($cmd = $laststep);
74 push(@hist,$cmd) if length($cmd) > 1;
75 ($i) = split(/\s+/,$cmd);
76 eval "\$cmd =~ $alias{$i}", print OUT $@ if $alias{$i};
77 $cmd =~ /^h$/ && do {
78 print OUT "
79T Stack trace.
80s Single step.
81n Next, steps over subroutine calls.
82f Finish current subroutine.
83c [line] Continue; optionally inserts a one-time-only breakpoint
84 at the specified line.
85<CR> Repeat last n or s.
86l min+incr List incr+1 lines starting at min.
87l min-max List lines.
88l line List line;
89l List next window.
90- List previous window.
91w line List window around line.
92l subname List subroutine.
93/pattern/ Search forwards for pattern; final / is optional.
94?pattern? Search backwards for pattern.
95L List breakpoints and actions.
96S List subroutine names.
97t Toggle trace mode.
98b [line] [condition]
99 Set breakpoint; line defaults to the current execution line;
100 condition breaks if it evaluates to true, defaults to \'1\'.
101b subname [condition]
102 Set breakpoint at first line of subroutine.
103d [line] Delete breakpoint.
104D Delete all breakpoints.
105a [line] command
106 Set an action to be done before the line is executed.
107 Sequence is: check for breakpoint, print line if necessary,
108 do action, prompt user if breakpoint or step, evaluate line.
109A Delete all actions.
110V package List all variables and values in package (default main).
111< command Define command before prompt.
112> command Define command after prompt.
113! number Redo command (default previous command).
114! -number Redo number\'th to last command.
115H -number Display last number commands (default all).
116q or ^D Quit.
117p expr Same as \"package main; print DB'OUT expr\".
118command Execute as a perl statement.
119
120";
121 next; };
122 $cmd =~ /^t$/ && do {
123 $trace = !$trace;
124 print OUT "Trace = ".($trace?"on":"off")."\n";
125 next; };
126 $cmd =~ /^S$/ && do {
127 foreach $subname (sort(keys %sub)) {
128 if ($subname =~ /^main'(.*)/) {
129 print OUT $1,"\n";
130 }
131 else {
132 print OUT $subname,"\n";
133 }
134 }
135 next; };
136 $cmd =~ /^V$/ && do {
137 $cmd = 'V main'; };
138 $cmd =~ /^V\s*(['A-Za-z_]['\w]*)$/ && do {
139 $packname = $1;
140 do 'dumpvar.pl' unless defined &main'dumpvar;
141 if (defined &main'dumpvar) {
142 &main'dumpvar($packname);
143 }
144 else {
145 print DB'OUT "dumpvar.pl not available.\n";
146 }
147 next; };
148 $cmd =~ /^l\s*(['A-Za-z_]['\w]*)/ && do {
149 $subname = $1;
150 $subname = "main'" . $subname unless $subname =~ /'/;
151 $subrange = $sub{$subname};
152 if ($subrange) {
153 if (eval($subrange) < -$window) {
154 $subrange =~ s/-.*/+/;
155 }
156 $cmd = "l $subrange";
157 } else {
158 print OUT "Subroutine $1 not found.\n";
159 next;
160 } };
161 $cmd =~ /^w\s*(\d*)$/ && do {
162 $incr = $window - 1;
163 $start = $1 if $1;
164 $start -= $preview;
165 $cmd = 'l ' . $start . '-' . ($start + $incr); };
166 $cmd =~ /^-$/ && do {
167 $incr = $window - 1;
168 $cmd = 'l ' . ($start-$window*2) . '+'; };
169 $cmd =~ /^l$/ && do {
170 $incr = $window - 1;
171 $cmd = 'l ' . $start . '-' . ($start + $incr); };
172 $cmd =~ /^l\s*(\d*)\+(\d*)$/ && do {
173 $start = $1 if $1;
174 $incr = $2;
175 $incr = $window - 1 unless $incr;
176 $cmd = 'l ' . $start . '-' . ($start + $incr); };
177 $cmd =~ /^l\s*(([\d\$\.]+)([-,]([\d\$\.]+))?)?/ && do {
178 $end = (!$2) ? $max : ($4 ? $4 : $2);
179 $end = $max if $end > $max;
180 $i = $2;
181 $i = $line if $i eq '.';
182 $i = 1 if $i < 1;
183 for (; $i <= $end; $i++) {
184 print OUT "$i:\t", $line[$i];
185 last if $signal;
186 }
187 $start = $i; # remember in case they want more
188 $start = $max if $start > $max;
189 next; };
190 $cmd =~ /^D$/ && do {
191 print OUT "Deleting all breakpoints...\n";
192 for ($i = 1; $i <= $max ; $i++) {
193 $stop[$i] = 0;
194 }
195 next; };
196 $cmd =~ /^L$/ && do {
197 for ($i = 1; $i <= $max; $i++) {
198 if ($stop[$i] || $action[$i]) {
199 print OUT "$i:\t", $line[$i];
200 print OUT " break if (", $stop[$i], ")\n"
201 if $stop[$i];
202 print OUT " action: ", $action[$i], "\n"
203 if $action[$i];
204 last if $signal;
205 }
206 }
207 next; };
208 $cmd =~ /^b\s*(['A-Za-z_]['\w]*)\s*(.*)/ && do {
209 $subname = $1;
210 $subname = "main'" . $subname unless $subname =~ /'/;
211 ($i) = split(/-/, $sub{$subname});
212 if ($i) {
213 ++$i while $line[$i] == 0 && $i < $#line;
214 $stop[$i] = $2 ? $2 : 1;
215 } else {
216 print OUT "Subroutine $1 not found.\n";
217 }
218 next; };
219 $cmd =~ /^b\s*(\d*)\s*(.*)/ && do {
220 $i = ($1?$1:$line);
221 if ($line[$i] == 0) {
222 print OUT "Line $i not breakable.\n";
223 } else {
224 $stop[$i] = $2 ? $2 : 1;
225 }
226 next; };
227 $cmd =~ /^d\s*(\d+)?/ && do {
228 $i = ($1?$1:$line);
229 $stop[$i] = '';
230 next; };
231 $cmd =~ /^A$/ && do {
232 for ($i = 1; $i <= $max ; $i++) {
233 $action[$i] = '';
234 }
235 next; };
236 $cmd =~ /^<\s*(.*)/ && do {
237 $pre = do action($1);
238 next; };
239 $cmd =~ /^>\s*(.*)/ && do {
240 $post = do action($1);
241 next; };
242 $cmd =~ /^a\s*(\d+)(\s+(.*))?/ && do {
243 $i = $1;
244 if ($line[$i] == 0) {
245 print OUT "Line $i may not have an action.\n";
246 } else {
247 $action[$i] = do action($3);
248 }
249 next; };
250 $cmd =~ /^n$/ && do {
251 $single = 2;
252 $laststep = $cmd;
253 last; };
254 $cmd =~ /^s$/ && do {
255 $single = 1;
256 $laststep = $cmd;
257 last; };
258 $cmd =~ /^c\s*(\d*)\s*$/ && do {
259 $i = $1;
260 if ($i) {
261 if ($line[$i] == 0) {
262 print OUT "Line $i not breakable.\n";
263 next;
264 }
265 $stop[$i] .= ";9"; # add one-time-only b.p.
266 }
267 for ($i=0; $i <= $#stack; ) {
268 $stack[$i++] &= ~1;
269 }
270 last; };
271 $cmd =~ /^f$/ && do {
272 $stack[$#stack] |= 2;
273 last; };
274 $cmd =~ /^T$/ && do {
275 for ($i=0; $i <= $#sub; ) {
276 print OUT $sub[$i++], "\n";
277 last if $signal;
278 }
279 next; };
280 $cmd =~ /^\/(.*)$/ && do {
281 $inpat = $1;
282 $inpat =~ s:([^\\])/$:$1:;
283 if ($inpat ne "") {
284 eval '$inpat =~ m'."\n$inpat\n";
285 if ($@ ne "") {
286 print OUT "$@";
287 next;
288 }
289 $pat = $inpat;
290 }
291 $end = $start;
292 eval '
293 for (;;) {
294 ++$start;
295 $start = 1 if ($start > $max);
296 last if ($start == $end);
297 if ($line[$start] =~ m'."\n$pat\n".'i) {
298 print OUT "$start:\t", $line[$start], "\n";
299 last;
300 }
301 } ';
302 print OUT "/$pat/: not found\n" if ($start == $end);
303 next; };
304 $cmd =~ /^\?(.*)$/ && do {
305 $inpat = $1;
306 $inpat =~ s:([^\\])\?$:$1:;
307 if ($inpat ne "") {
308 eval '$inpat =~ m'."\n$inpat\n";
309 if ($@ ne "") {
310 print OUT "$@";
311 next;
312 }
313 $pat = $inpat;
314 }
315 $end = $start;
316 eval '
317 for (;;) {
318 --$start;
319 $start = $max if ($start <= 0);
320 last if ($start == $end);
321 if ($line[$start] =~ m'."\n$pat\n".'i) {
322 print OUT "$start:\t", $line[$start], "\n";
323 last;
324 }
325 } ';
326 print OUT "?$pat?: not found\n" if ($start == $end);
327 next; };
328 $cmd =~ /^!+\s*(-)?(\d+)?$/ && do {
329 pop(@hist) if length($cmd) > 1;
330 $i = ($1?($#hist-($2?$2:1)):($2?$2:$#hist));
331 $cmd = $hist[$i] . "\n";
332 print OUT $cmd;
333 redo; };
334 $cmd =~ /^!(.+)$/ && do {
335 $pat = "^$1";
336 pop(@hist) if length($cmd) > 1;
337 for ($i = $#hist; $i; --$i) {
338 last if $hist[$i] =~ $pat;
339 }
340 if (!$i) {
341 print OUT "No such command!\n\n";
342 next;
343 }
344 $cmd = $hist[$i] . "\n";
345 print OUT $cmd;
346 redo; };
347 $cmd =~ /^H\s*(-(\d+))?/ && do {
348 $end = $2?($#hist-$2):0;
349 $hist = 0 if $hist < 0;
350 for ($i=$#hist; $i>$end; $i--) {
351 print OUT "$i: ",$hist[$i],"\n"
352 unless $hist[$i] =~ /^.?$/;
353 };
354 next; };
355 $cmd =~ s/^p( .*)?$/print DB'OUT$1/;
356 {
357 package main;
358 eval $DB'cmd;
359 }
360 print OUT $@,"\n";
361 }
362 if ($post) {
363 package main;
364 eval $DB'post; print DB'OUT $@;
365 }
366 }
367}
368
369sub action {
370 local($action) = @_;
371 while ($action =~ s/\\$//) {
372 print OUT "+ ";
373 $action .= <IN>;
374 }
375 $action;
376}
377
378sub catch {
379 $signal = 1;
380}
381
382sub sub {
383 push(@stack, $single);
384 $single &= 1;
385 $single |= 4 if $#stack == $deep;
386 local(@args) = @_;
387 for (@args) {
388 if (/^Stab/ && length($_) == length($_main{'_main'})) {
389 $_ = sprintf("%s",$_);
390 print "ARG: $_\n";
391 }
392 else {
393 s/'/\\'/g;
394 s/(.*)/'$1'/ unless /^-?[\d.]+$/;
395 }
396 }
397 push(@sub, $sub . '(' . join(', ', @args) . ') from ' . $line);
398 if (wantarray) {
399 @i = &$sub;
400 }
401 else {
402 $i = &$sub;
403 @i = $i;
404 }
405 --$#sub;
406 $single |= pop(@stack);
407 @i;
408}
409
410$single = 1; # so it stops on first executable statement
411$max = $#line;
412@hist = ('?');
413$SIG{'INT'} = "DB'catch";
414$deep = 100; # warning if stack gets this deep
415$window = 10;
416$preview = 3;
417
418@stack = (0);
419@args = @ARGV;
420for (@args) {
421 s/'/\\'/g;
422 s/(.*)/'$1'/ unless /^-?[\d.]+$/;
423}
424push(@sub, 'main(' . join(', ', @args) . ")" );
425$sub = 'main';
426
427if (-f '.perldb') {
428 do './.perldb';
429}
430elsif (-f "$ENV{'LOGDIR'}/.perldb") {
431 do "$ENV{'LOGDIR'}/.perldb";
432}
433elsif (-f "$ENV{'HOME'}/.perldb") {
434 do "$ENV{'HOME'}/.perldb";
435}
436
4371;