Mercurial > octave
annotate src/pt-bp.cc @ 7715:5b4d278ec828
parse scripts completely before executing
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Wed, 16 Apr 2008 15:09:56 -0400 |
parents | f3d508351e49 |
children | 73c4516fae10 |
rev | line source |
---|---|
3771 | 1 /* |
2 | |
7017 | 3 Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Ben Sapp |
3771 | 4 |
5 This file is part of Octave. | |
6 | |
7 Octave is free software; you can redistribute it and/or modify it | |
8 under the terms of the GNU General Public License as published by the | |
7016 | 9 Free Software Foundation; either version 3 of the License, or (at your |
10 option) any later version. | |
3771 | 11 |
12 Octave is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
7016 | 18 along with Octave; see the file COPYING. If not, see |
19 <http://www.gnu.org/licenses/>. | |
3771 | 20 |
21 */ | |
22 | |
23 #ifdef HAVE_CONFIG_H | |
24 #include <config.h> | |
25 #endif | |
26 | |
27 #include "ov-usr-fcn.h" | |
28 #include "ov-list.h" | |
29 #include "pager.h" | |
30 #include "pt-all.h" | |
31 | |
4185 | 32 // TRUE means SIGINT should put us in the debugger at the next |
33 // available breakpoint. | |
34 bool octave_debug_on_interrupt_state = false; | |
35 | |
3771 | 36 void |
37 tree_breakpoint::take_action (tree &tr) | |
38 { | |
39 if (act == set) | |
40 { | |
41 tr.set_breakpoint (); | |
42 line = tr.line (); | |
43 found = true; | |
44 } | |
45 else if (act == clear) | |
46 { | |
47 tr.delete_breakpoint (); | |
48 found = true; | |
49 } | |
50 else if (act == list) | |
51 { | |
52 if (tr.is_breakpoint ()) | |
53 { | |
4233 | 54 bp_list.append (octave_value (tr.line ())); |
3771 | 55 line = tr.line () + 1; |
56 } | |
57 } | |
58 else | |
59 panic_impossible (); | |
60 | |
61 return; | |
62 } | |
63 | |
64 void | |
65 tree_breakpoint::visit_while_command (tree_while_command& cmd) | |
66 { | |
67 if (found) | |
68 return; | |
69 | |
70 if (cmd.line () >= line) | |
71 take_action (cmd); | |
72 | |
73 tree_expression *expr = cmd.condition (); | |
74 | |
75 if (expr) | |
76 expr->accept (*this); | |
77 | |
4274 | 78 tree_statement_list *lst = cmd.body (); |
3771 | 79 |
4274 | 80 if (lst) |
81 lst->accept (*this); | |
3771 | 82 } |
83 | |
84 void | |
85 tree_breakpoint::visit_do_until_command (tree_do_until_command& cmd) | |
86 { | |
3805 | 87 if (found) |
88 return; | |
3771 | 89 |
90 if (cmd.line () >= line) | |
91 take_action (cmd); | |
92 | |
3805 | 93 tree_statement_list *lst = cmd.body (); |
94 | |
3771 | 95 if (lst) |
96 lst->accept (*this); | |
97 | |
98 if (found) | |
99 return; | |
100 | |
101 tree_expression *expr = cmd.condition (); | |
102 | |
103 if (expr) | |
104 expr->accept (*this); | |
105 } | |
106 | |
107 void | |
108 tree_breakpoint::visit_argument_list (tree_argument_list& lst) | |
109 { | |
110 if (found) | |
111 return; | |
112 | |
4219 | 113 for (tree_argument_list::iterator p = lst.begin (); p != lst.end (); p++) |
3771 | 114 { |
4219 | 115 tree_expression *elt = *p; |
3771 | 116 |
117 if (elt) | |
118 elt->accept (*this); | |
119 } | |
120 } | |
121 | |
122 void | |
123 tree_breakpoint::visit_binary_expression (tree_binary_expression& expr) | |
124 { | |
125 if (found) | |
126 return; | |
127 | |
128 tree_expression *lhs = expr.lhs (); | |
129 tree_expression *rhs = expr.rhs (); | |
130 | |
131 if (lhs && lhs->line () >= line) | |
3805 | 132 lhs->accept (*this); |
3771 | 133 |
134 if (rhs && rhs->line () >= line) | |
3805 | 135 rhs->accept (*this); |
3771 | 136 } |
137 | |
138 void | |
4207 | 139 tree_breakpoint::visit_break_command (tree_break_command& cmd) |
3771 | 140 { |
141 if (found) | |
142 return; | |
143 | |
144 if (cmd.line () >= line) | |
145 take_action (cmd); | |
146 } | |
147 | |
148 void | |
149 tree_breakpoint::visit_colon_expression (tree_colon_expression& expr) | |
150 { | |
151 if (found) | |
152 return; | |
153 | |
3805 | 154 if (expr.line () >= line) |
155 take_action (expr); | |
156 | |
3771 | 157 tree_expression *base = expr.base (); |
158 | |
159 if (base) | |
160 base->accept (*this); | |
161 | |
162 tree_expression *increment = expr.increment (); | |
163 | |
164 if (increment) | |
165 increment->accept (*this); | |
166 | |
167 tree_expression *limit = expr.limit (); | |
168 | |
169 if (limit) | |
170 limit->accept (*this); | |
171 } | |
172 | |
173 void | |
4207 | 174 tree_breakpoint::visit_continue_command (tree_continue_command& cmd) |
3771 | 175 { |
176 if (found) | |
177 return; | |
178 | |
179 if (cmd.line () >= line) | |
180 take_action (cmd); | |
181 } | |
182 | |
183 void | |
184 tree_breakpoint::visit_decl_command (tree_decl_command& cmd) | |
185 { | |
186 if (found) | |
187 return; | |
188 | |
7205 | 189 if (cmd.line () >= line) |
190 take_action (cmd); | |
191 | |
3771 | 192 tree_decl_init_list *init_list = cmd.initializer_list (); |
193 | |
194 if (init_list) | |
195 init_list->accept (*this); | |
196 } | |
197 | |
198 void | |
199 tree_breakpoint::visit_decl_elt (tree_decl_elt& cmd) | |
200 { | |
201 if (found) | |
202 return; | |
203 | |
204 tree_identifier *ident = cmd.ident (); | |
205 | |
206 if (ident) | |
207 ident->accept (*this); | |
208 | |
209 tree_expression *expr = cmd.expression (); | |
210 | |
211 if (expr) | |
212 expr->accept (*this); | |
213 | |
214 } | |
215 | |
216 void | |
217 tree_breakpoint::visit_decl_init_list (tree_decl_init_list& lst) | |
218 { | |
219 if (found) | |
220 return; | |
221 | |
4219 | 222 for (tree_decl_init_list::iterator p = lst.begin (); p != lst.end (); p++) |
3771 | 223 { |
4219 | 224 tree_decl_elt *elt = *p; |
3771 | 225 |
226 if (elt) | |
227 elt->accept (*this); | |
228 } | |
229 } | |
230 | |
231 void | |
232 tree_breakpoint::visit_simple_for_command (tree_simple_for_command& cmd) | |
233 { | |
234 if (found) | |
235 return; | |
236 | |
237 if (cmd.line () >= line) | |
238 take_action (cmd); | |
239 | |
240 tree_expression *expr = cmd.control_expr (); | |
241 | |
242 if (expr) | |
243 expr->accept (*this); | |
244 | |
4274 | 245 tree_statement_list *lst = cmd.body (); |
3771 | 246 |
4274 | 247 if (lst) |
248 lst->accept (*this); | |
3771 | 249 } |
250 | |
251 void | |
252 tree_breakpoint::visit_complex_for_command (tree_complex_for_command& cmd) | |
253 { | |
254 if (found) | |
255 return; | |
256 | |
257 if (cmd.line () >= line) | |
258 take_action (cmd); | |
259 | |
260 tree_expression *expr = cmd.control_expr (); | |
261 | |
262 if (expr) | |
263 expr->accept (*this); | |
264 | |
4274 | 265 tree_statement_list *lst = cmd.body (); |
3771 | 266 |
4274 | 267 if (lst) |
268 lst->accept (*this); | |
3771 | 269 |
270 } | |
271 | |
272 void | |
7715
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7205
diff
changeset
|
273 tree_breakpoint::visit_octave_user_script (octave_user_script&) |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7205
diff
changeset
|
274 { |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7205
diff
changeset
|
275 // FIXME -- should anything happen here? |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7205
diff
changeset
|
276 } |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7205
diff
changeset
|
277 |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7205
diff
changeset
|
278 void |
4661 | 279 tree_breakpoint::visit_octave_user_function (octave_user_function&) |
3771 | 280 { |
4661 | 281 // We should not visit octave user functions because the function we |
282 // are currently in is the function where the breakpoint was | |
283 // requested. | |
3771 | 284 } |
285 | |
286 void | |
4661 | 287 tree_breakpoint::visit_octave_user_function_header (octave_user_function&) |
3771 | 288 { |
4661 | 289 // Do nothing. |
3771 | 290 } |
291 | |
292 void | |
4661 | 293 tree_breakpoint::visit_octave_user_function_trailer (octave_user_function&) |
3771 | 294 { |
4661 | 295 // Do nothing. |
3771 | 296 } |
297 | |
7715
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7205
diff
changeset
|
298 void |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7205
diff
changeset
|
299 tree_breakpoint::visit_function_def (tree_function_def& fdef) |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7205
diff
changeset
|
300 { |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7205
diff
changeset
|
301 if (found) |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7205
diff
changeset
|
302 return; |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7205
diff
changeset
|
303 |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7205
diff
changeset
|
304 octave_function *fcn = fdef.function (); |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7205
diff
changeset
|
305 |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7205
diff
changeset
|
306 if (fcn) |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7205
diff
changeset
|
307 fcn->accept (*this); |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7205
diff
changeset
|
308 } |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7205
diff
changeset
|
309 |
3771 | 310 void |
311 tree_breakpoint::visit_identifier (tree_identifier& id) | |
312 { | |
313 if (found) | |
314 return; | |
315 | |
316 if (id.line () >= line ) | |
317 take_action (id); | |
318 } | |
319 | |
320 void | |
321 tree_breakpoint::visit_if_clause (tree_if_clause& cmd) | |
322 { | |
323 if (found) | |
324 return; | |
325 | |
326 tree_expression *expr = cmd.condition (); | |
327 | |
328 if (expr) | |
329 expr->accept (*this); | |
330 | |
4274 | 331 tree_statement_list *lst = cmd.commands (); |
3771 | 332 |
4274 | 333 if (lst) |
334 lst->accept (*this); | |
3771 | 335 } |
336 | |
337 void | |
338 tree_breakpoint::visit_if_command (tree_if_command& cmd) | |
339 { | |
340 if (found) | |
341 return; | |
342 | |
4274 | 343 tree_if_command_list *lst = cmd.cmd_list (); |
3771 | 344 |
4274 | 345 if (lst) |
346 lst->accept (*this); | |
3771 | 347 } |
348 | |
349 void | |
350 tree_breakpoint::visit_if_command_list (tree_if_command_list& lst) | |
351 { | |
352 if (found) | |
353 return; | |
354 | |
4219 | 355 for (tree_if_command_list::iterator p = lst.begin (); p != lst.end (); p++) |
3771 | 356 { |
4219 | 357 tree_if_clause *elt = *p; |
3771 | 358 |
359 if (elt) | |
360 elt->accept (*this); | |
361 } | |
362 } | |
363 | |
364 void | |
365 tree_breakpoint::visit_index_expression (tree_index_expression& cmd) | |
366 { | |
367 if (found) | |
368 return; | |
369 | |
3933 | 370 tree_expression *expr = cmd.expression (); |
371 | |
372 if (expr && expr->line () >= line) | |
373 take_action (*expr); | |
374 | |
4219 | 375 std::list<tree_argument_list *> lst = cmd.arg_lists (); |
376 | |
3933 | 377 |
378 if (! lst.empty ()) | |
3930 | 379 { |
4219 | 380 for (std::list<tree_argument_list *>::iterator p = lst.begin (); |
381 p != lst.end (); | |
382 p++) | |
3933 | 383 { |
4219 | 384 tree_argument_list *elt = *p; |
3771 | 385 |
5459 | 386 if (elt) |
387 elt->accept (*this); | |
3933 | 388 } |
3930 | 389 } |
3771 | 390 } |
391 | |
392 void | |
393 tree_breakpoint::visit_matrix (tree_matrix& mat) | |
394 { | |
395 if (found) | |
396 return; | |
397 | |
4219 | 398 tree_matrix::iterator p = mat.begin (); |
3771 | 399 |
4219 | 400 while (p != mat.end ()) |
3771 | 401 { |
4219 | 402 tree_argument_list *elt = *p++; |
3771 | 403 |
404 if (elt) | |
405 elt->accept (*this); | |
406 } | |
407 } | |
408 | |
409 void | |
410 tree_breakpoint::visit_cell (tree_cell& cell) | |
411 { | |
412 if (found) | |
413 return; | |
414 | |
4219 | 415 tree_cell::iterator p = cell.begin (); |
3771 | 416 |
4219 | 417 while (p != cell.end ()) |
3771 | 418 { |
4219 | 419 tree_argument_list *elt = *p++; |
3771 | 420 |
421 if (elt) | |
422 elt->accept (*this); | |
423 } | |
424 } | |
425 | |
426 void | |
427 tree_breakpoint::visit_multi_assignment (tree_multi_assignment& expr) | |
428 { | |
429 if (found) | |
430 return; | |
431 | |
4274 | 432 tree_argument_list *lst = expr.left_hand_side (); |
3771 | 433 |
4274 | 434 if (lst) |
435 lst->accept (*this); | |
3771 | 436 |
437 tree_expression *rhs = expr.right_hand_side (); | |
438 | |
439 if (rhs) | |
440 rhs->accept (*this); | |
441 } | |
442 | |
443 void | |
444 tree_breakpoint::visit_no_op_command (tree_no_op_command& cmd) | |
445 { | |
446 if (found) | |
447 return; | |
448 | |
449 if (cmd.line () >= line) | |
450 take_action (cmd); | |
451 } | |
452 | |
5861 | 453 void |
454 tree_breakpoint::visit_anon_fcn_handle (tree_anon_fcn_handle& afh) | |
455 { | |
456 if (found) | |
457 return; | |
458 | |
459 if (afh.line () >= line) | |
460 take_action (afh); | |
461 } | |
462 | |
3771 | 463 void |
464 tree_breakpoint::visit_constant (tree_constant& cmd) | |
465 { | |
466 if (found) | |
467 return; | |
468 | |
469 if (cmd.line () >= line) | |
470 take_action (cmd); | |
471 } | |
472 | |
473 void | |
4342 | 474 tree_breakpoint::visit_fcn_handle (tree_fcn_handle& fh) |
475 { | |
476 if (found) | |
477 return; | |
478 | |
479 if (fh.line () >= line) | |
480 take_action (fh); | |
481 } | |
482 | |
483 void | |
3771 | 484 tree_breakpoint::visit_parameter_list (tree_parameter_list& lst) |
485 { | |
486 if (found) | |
487 return; | |
488 | |
4219 | 489 tree_parameter_list::iterator p = lst.begin (); |
3771 | 490 |
4219 | 491 while (p != lst.end ()) |
3771 | 492 { |
6215 | 493 tree_decl_elt *elt = *p++; |
3771 | 494 |
495 if (elt) | |
496 elt->accept (*this); | |
497 } | |
498 } | |
499 | |
500 void | |
501 tree_breakpoint::visit_postfix_expression (tree_postfix_expression& expr) | |
502 { | |
503 if (found) | |
504 return; | |
505 | |
506 if (expr.line () >= line) | |
507 take_action (expr); | |
508 | |
509 tree_expression *e = expr.operand (); | |
510 | |
511 if (e) | |
512 e->accept (*this); | |
513 } | |
514 | |
515 void | |
516 tree_breakpoint::visit_prefix_expression (tree_prefix_expression& expr) | |
517 { | |
518 if (found) | |
519 return; | |
520 | |
521 if (expr.line () >= line) | |
522 take_action (expr); | |
523 | |
524 tree_expression *e = expr.operand (); | |
525 | |
526 if (e) | |
527 e->accept (*this); | |
528 } | |
529 | |
530 void | |
4207 | 531 tree_breakpoint::visit_return_command (tree_return_command& cmd) |
3771 | 532 { |
533 if (found) | |
534 return; | |
535 | |
536 if (cmd.line () >= line) | |
537 take_action (cmd); | |
538 } | |
539 | |
540 void | |
541 tree_breakpoint::visit_return_list (tree_return_list& lst) | |
542 { | |
543 if (found) | |
544 return; | |
545 | |
4219 | 546 tree_return_list::iterator p = lst.begin (); |
3771 | 547 |
4219 | 548 while (p != lst.end ()) |
3771 | 549 { |
4219 | 550 tree_index_expression *elt = *p++; |
3771 | 551 |
552 if (elt) | |
553 elt->accept (*this); | |
554 } | |
555 } | |
556 | |
557 void | |
558 tree_breakpoint::visit_simple_assignment (tree_simple_assignment& expr) | |
559 { | |
560 if (found) | |
561 return; | |
562 | |
563 if (expr.line () >= line) | |
564 take_action (expr); | |
565 | |
566 } | |
567 | |
568 void | |
569 tree_breakpoint::visit_statement (tree_statement& stmt) | |
570 { | |
571 if (found) | |
572 return; | |
573 | |
574 tree_command *cmd = stmt.command (); | |
575 | |
576 if (cmd) | |
577 cmd->accept (*this); | |
578 else | |
579 { | |
580 tree_expression *expr = stmt.expression (); | |
581 | |
582 if (expr) | |
583 expr->accept (*this); | |
584 } | |
585 } | |
586 | |
587 void | |
588 tree_breakpoint::visit_statement_list (tree_statement_list& lst) | |
589 { | |
590 if (found) | |
591 return; | |
592 | |
4219 | 593 for (tree_statement_list::iterator p = lst.begin (); p != lst.end (); p++) |
3771 | 594 { |
4219 | 595 tree_statement *elt = *p; |
3771 | 596 |
597 if (elt) | |
598 elt->accept (*this); | |
599 } | |
600 } | |
601 | |
602 void | |
603 tree_breakpoint::visit_switch_case (tree_switch_case& cmd) | |
604 { | |
605 if (found) | |
606 return; | |
607 | |
608 // Disallow breakpoints on the label. | |
609 | |
610 tree_statement_list *lst = cmd.commands (); | |
611 | |
612 if (lst) | |
613 lst->accept (*this); | |
614 } | |
615 | |
616 void | |
617 tree_breakpoint::visit_switch_case_list (tree_switch_case_list& lst) | |
618 { | |
619 if (found) | |
620 return; | |
621 | |
4219 | 622 tree_switch_case_list::iterator p = lst.begin (); |
3771 | 623 |
4219 | 624 while (p != lst.end ()) |
3771 | 625 { |
4219 | 626 tree_switch_case *elt = *p++; |
3771 | 627 |
628 if (elt) | |
629 elt->accept (*this); | |
630 } | |
631 } | |
632 | |
633 | |
634 void | |
635 tree_breakpoint::visit_switch_command (tree_switch_command& cmd) | |
636 { | |
637 if (found) | |
638 return; | |
639 | |
640 tree_expression *expr = cmd.switch_value (); | |
641 | |
642 if (expr) | |
643 expr->accept (*this); | |
644 | |
645 tree_switch_case_list *lst = cmd.case_list (); | |
646 | |
647 if (lst) | |
648 lst->accept (*this); | |
649 } | |
650 | |
651 void | |
652 tree_breakpoint::visit_try_catch_command (tree_try_catch_command& cmd) | |
653 { | |
654 if (found) | |
655 return; | |
656 | |
657 if (cmd.line () >= line) | |
658 take_action (cmd); | |
659 | |
660 tree_statement_list *try_code = cmd.body (); | |
661 | |
662 if (try_code) | |
663 try_code->accept (*this); | |
664 | |
665 tree_statement_list *catch_code = cmd.cleanup (); | |
666 | |
667 if (catch_code) | |
668 catch_code->accept (*this); | |
669 } | |
670 | |
671 void | |
672 tree_breakpoint::visit_unwind_protect_command (tree_unwind_protect_command& cmd) | |
673 { | |
674 if (found) | |
675 return; | |
676 | |
677 if (cmd.line () >= line) | |
678 take_action (cmd); | |
679 | |
4064 | 680 tree_statement_list *lstA = cmd.body (); |
3771 | 681 |
4064 | 682 if (lstA) |
683 lstA->accept (*this); | |
3771 | 684 |
4064 | 685 tree_statement_list *lstB = cmd.cleanup (); |
3771 | 686 |
4064 | 687 if (lstB) |
688 lstB->accept (*this); | |
3771 | 689 } |
690 | |
691 /* | |
692 ;;; Local Variables: *** | |
693 ;;; mode: C++ *** | |
694 ;;; End: *** | |
695 */ |