00001 /* 00002 00003 Copyright (C) 2001-2012 Ben Sapp 00004 00005 This file is part of Octave. 00006 00007 Octave is free software; you can redistribute it and/or modify it 00008 under the terms of the GNU General Public License as published by the 00009 Free Software Foundation; either version 3 of the License, or (at your 00010 option) any later version. 00011 00012 Octave is distributed in the hope that it will be useful, but WITHOUT 00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00014 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 00015 for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with Octave; see the file COPYING. If not, see 00019 <http://www.gnu.org/licenses/>. 00020 00021 */ 00022 00023 #ifdef HAVE_CONFIG_H 00024 #include <config.h> 00025 #endif 00026 00027 #include "ov-usr-fcn.h" 00028 #include "pager.h" 00029 #include "pt-all.h" 00030 00031 // TRUE means SIGINT should put us in the debugger at the next 00032 // available breakpoint. 00033 bool octave_debug_on_interrupt_state = false; 00034 00035 void 00036 tree_breakpoint::visit_while_command (tree_while_command& cmd) 00037 { 00038 if (cmd.line () >= line) 00039 take_action (cmd); 00040 00041 if (! found) 00042 { 00043 tree_statement_list *lst = cmd.body (); 00044 00045 if (lst) 00046 lst->accept (*this); 00047 } 00048 } 00049 00050 void 00051 tree_breakpoint::visit_do_until_command (tree_do_until_command& cmd) 00052 { 00053 if (! found) 00054 { 00055 tree_statement_list *lst = cmd.body (); 00056 00057 if (lst) 00058 lst->accept (*this); 00059 00060 if (! found) 00061 { 00062 if (cmd.line () >= line) 00063 take_action (cmd); 00064 } 00065 } 00066 } 00067 00068 void 00069 tree_breakpoint::visit_argument_list (tree_argument_list&) 00070 { 00071 panic_impossible (); 00072 } 00073 00074 void 00075 tree_breakpoint::visit_binary_expression (tree_binary_expression&) 00076 { 00077 panic_impossible (); 00078 } 00079 00080 void 00081 tree_breakpoint::visit_break_command (tree_break_command& cmd) 00082 { 00083 if (cmd.line () >= line) 00084 take_action (cmd); 00085 } 00086 00087 void 00088 tree_breakpoint::visit_colon_expression (tree_colon_expression&) 00089 { 00090 panic_impossible (); 00091 } 00092 00093 void 00094 tree_breakpoint::visit_continue_command (tree_continue_command& cmd) 00095 { 00096 if (cmd.line () >= line) 00097 take_action (cmd); 00098 } 00099 00100 void 00101 tree_breakpoint::do_decl_command (tree_decl_command& cmd) 00102 { 00103 if (cmd.line () >= line) 00104 take_action (cmd); 00105 } 00106 00107 void 00108 tree_breakpoint::visit_global_command (tree_global_command& cmd) 00109 { 00110 do_decl_command (cmd); 00111 } 00112 00113 void 00114 tree_breakpoint::visit_static_command (tree_static_command& cmd) 00115 { 00116 do_decl_command (cmd); 00117 } 00118 00119 void 00120 tree_breakpoint::visit_decl_elt (tree_decl_elt&) 00121 { 00122 panic_impossible (); 00123 } 00124 00125 void 00126 tree_breakpoint::visit_decl_init_list (tree_decl_init_list&) 00127 { 00128 panic_impossible (); 00129 } 00130 00131 void 00132 tree_breakpoint::visit_simple_for_command (tree_simple_for_command& cmd) 00133 { 00134 if (cmd.line () >= line) 00135 take_action (cmd); 00136 00137 if (! found) 00138 { 00139 tree_statement_list *lst = cmd.body (); 00140 00141 if (lst) 00142 lst->accept (*this); 00143 } 00144 } 00145 00146 void 00147 tree_breakpoint::visit_complex_for_command (tree_complex_for_command& cmd) 00148 { 00149 if (cmd.line () >= line) 00150 take_action (cmd); 00151 00152 if (! found) 00153 { 00154 tree_statement_list *lst = cmd.body (); 00155 00156 if (lst) 00157 lst->accept (*this); 00158 } 00159 } 00160 00161 void 00162 tree_breakpoint::visit_octave_user_script (octave_user_script& fcn) 00163 { 00164 tree_statement_list *cmd_list = fcn.body (); 00165 00166 if (cmd_list) 00167 cmd_list->accept (*this); 00168 } 00169 00170 void 00171 tree_breakpoint::visit_octave_user_function (octave_user_function& fcn) 00172 { 00173 tree_statement_list *cmd_list = fcn.body (); 00174 00175 if (cmd_list) 00176 cmd_list->accept (*this); 00177 } 00178 00179 void 00180 tree_breakpoint::visit_octave_user_function_header (octave_user_function&) 00181 { 00182 panic_impossible (); 00183 } 00184 00185 void 00186 tree_breakpoint::visit_octave_user_function_trailer (octave_user_function&) 00187 { 00188 panic_impossible (); 00189 } 00190 00191 void 00192 tree_breakpoint::visit_function_def (tree_function_def& fdef) 00193 { 00194 octave_value fcn = fdef.function (); 00195 00196 octave_function *f = fcn.function_value (); 00197 00198 if (f) 00199 f->accept (*this); 00200 } 00201 00202 void 00203 tree_breakpoint::visit_identifier (tree_identifier&) 00204 { 00205 panic_impossible (); 00206 } 00207 00208 void 00209 tree_breakpoint::visit_if_clause (tree_if_clause&) 00210 { 00211 panic_impossible (); 00212 } 00213 00214 void 00215 tree_breakpoint::visit_if_command (tree_if_command& cmd) 00216 { 00217 if (cmd.line () >= line) 00218 take_action (cmd); 00219 00220 if (! found) 00221 { 00222 tree_if_command_list *lst = cmd.cmd_list (); 00223 00224 if (lst) 00225 lst->accept (*this); 00226 } 00227 } 00228 00229 void 00230 tree_breakpoint::visit_if_command_list (tree_if_command_list& lst) 00231 { 00232 for (tree_if_command_list::iterator p = lst.begin (); p != lst.end (); p++) 00233 { 00234 tree_if_clause *t = *p; 00235 00236 if (t->line () >= line) 00237 take_action (*t); 00238 00239 if (! found) 00240 { 00241 tree_statement_list *stmt_lst = t->commands (); 00242 00243 if (stmt_lst) 00244 stmt_lst->accept (*this); 00245 } 00246 00247 if (found) 00248 break; 00249 } 00250 } 00251 00252 void 00253 tree_breakpoint::visit_index_expression (tree_index_expression&) 00254 { 00255 panic_impossible (); 00256 } 00257 00258 void 00259 tree_breakpoint::visit_matrix (tree_matrix&) 00260 { 00261 panic_impossible (); 00262 } 00263 00264 void 00265 tree_breakpoint::visit_cell (tree_cell&) 00266 { 00267 panic_impossible (); 00268 } 00269 00270 void 00271 tree_breakpoint::visit_multi_assignment (tree_multi_assignment&) 00272 { 00273 panic_impossible (); 00274 } 00275 00276 void 00277 tree_breakpoint::visit_no_op_command (tree_no_op_command& cmd) 00278 { 00279 if (cmd.is_end_of_fcn_or_script () && cmd.line () >= line) 00280 take_action (cmd); 00281 } 00282 00283 void 00284 tree_breakpoint::visit_anon_fcn_handle (tree_anon_fcn_handle&) 00285 { 00286 panic_impossible (); 00287 } 00288 00289 void 00290 tree_breakpoint::visit_constant (tree_constant&) 00291 { 00292 panic_impossible (); 00293 } 00294 00295 void 00296 tree_breakpoint::visit_fcn_handle (tree_fcn_handle&) 00297 { 00298 panic_impossible (); 00299 } 00300 00301 void 00302 tree_breakpoint::visit_parameter_list (tree_parameter_list&) 00303 { 00304 panic_impossible (); 00305 } 00306 00307 void 00308 tree_breakpoint::visit_postfix_expression (tree_postfix_expression&) 00309 { 00310 panic_impossible (); 00311 } 00312 00313 void 00314 tree_breakpoint::visit_prefix_expression (tree_prefix_expression&) 00315 { 00316 panic_impossible (); 00317 } 00318 00319 void 00320 tree_breakpoint::visit_return_command (tree_return_command& cmd) 00321 { 00322 if (cmd.line () >= line) 00323 take_action (cmd); 00324 } 00325 00326 void 00327 tree_breakpoint::visit_return_list (tree_return_list&) 00328 { 00329 panic_impossible (); 00330 } 00331 00332 void 00333 tree_breakpoint::visit_simple_assignment (tree_simple_assignment&) 00334 { 00335 panic_impossible (); 00336 } 00337 00338 void 00339 tree_breakpoint::visit_statement (tree_statement& stmt) 00340 { 00341 if (stmt.is_command ()) 00342 { 00343 tree_command *cmd = stmt.command (); 00344 00345 cmd->accept (*this); 00346 } 00347 else 00348 { 00349 if (stmt.line () >= line) 00350 take_action (stmt); 00351 } 00352 } 00353 00354 void 00355 tree_breakpoint::visit_statement_list (tree_statement_list& lst) 00356 { 00357 for (tree_statement_list::iterator p = lst.begin (); p != lst.end (); p++) 00358 { 00359 tree_statement *elt = *p; 00360 00361 if (elt) 00362 { 00363 elt->accept (*this); 00364 00365 if (found) 00366 break; 00367 } 00368 } 00369 } 00370 00371 void 00372 tree_breakpoint::visit_switch_case (tree_switch_case&) 00373 { 00374 panic_impossible (); 00375 } 00376 00377 void 00378 tree_breakpoint::visit_switch_case_list (tree_switch_case_list& lst) 00379 { 00380 for (tree_switch_case_list::iterator p = lst.begin (); p != lst.end (); p++) 00381 { 00382 tree_switch_case *t = *p; 00383 00384 if (t->line () >= line) 00385 take_action (*t); 00386 00387 if (! found) 00388 { 00389 tree_statement_list *stmt_lst = t->commands (); 00390 00391 if (stmt_lst) 00392 stmt_lst->accept (*this); 00393 } 00394 00395 if (found) 00396 break; 00397 } 00398 } 00399 00400 void 00401 tree_breakpoint::visit_switch_command (tree_switch_command& cmd) 00402 { 00403 if (cmd.line () >= line) 00404 take_action (cmd); 00405 00406 if (! found) 00407 { 00408 tree_switch_case_list *lst = cmd.case_list (); 00409 00410 if (lst) 00411 lst->accept (*this); 00412 } 00413 } 00414 00415 void 00416 tree_breakpoint::visit_try_catch_command (tree_try_catch_command& cmd) 00417 { 00418 tree_statement_list *try_code = cmd.body (); 00419 00420 if (try_code) 00421 try_code->accept (*this); 00422 00423 if (! found) 00424 { 00425 tree_statement_list *catch_code = cmd.cleanup (); 00426 00427 if (catch_code) 00428 catch_code->accept (*this); 00429 } 00430 } 00431 00432 void 00433 tree_breakpoint::visit_unwind_protect_command (tree_unwind_protect_command& cmd) 00434 { 00435 tree_statement_list *body = cmd.body (); 00436 00437 if (body) 00438 body->accept (*this); 00439 00440 if (! found) 00441 { 00442 tree_statement_list *cleanup = cmd.cleanup (); 00443 00444 if (cleanup) 00445 cleanup->accept (*this); 00446 } 00447 } 00448 00449 void 00450 tree_breakpoint::take_action (tree& tr) 00451 { 00452 if (act == set) 00453 { 00454 tr.set_breakpoint (); 00455 line = tr.line (); 00456 found = true; 00457 } 00458 else if (act == clear) 00459 { 00460 if (tr.is_breakpoint ()) 00461 { 00462 tr.delete_breakpoint (); 00463 found = true; 00464 } 00465 } 00466 else if (act == list) 00467 { 00468 if (tr.is_breakpoint ()) 00469 bp_list.append (octave_value (tr.line ())); 00470 } 00471 else 00472 panic_impossible (); 00473 } 00474 00475 void 00476 tree_breakpoint::take_action (tree_statement& stmt) 00477 { 00478 int lineno = stmt.line (); 00479 00480 if (act == set) 00481 { 00482 stmt.set_breakpoint (); 00483 line = lineno; 00484 found = true; 00485 } 00486 else if (act == clear) 00487 { 00488 if (stmt.is_breakpoint ()) 00489 { 00490 stmt.delete_breakpoint (); 00491 found = true; 00492 } 00493 } 00494 else if (act == list) 00495 { 00496 if (stmt.is_breakpoint ()) 00497 bp_list.append (octave_value (lineno)); 00498 } 00499 else 00500 panic_impossible (); 00501 }