diff libinterp/parse-tree/pt-stmt.cc @ 21157:94fc5f13d51b

dbstop: conditional breakpoint, dbstop if caught error etc. (bug #46795) * debug.cc (parse_dbfunction_params): Accept "in", "at" and "if" tokens. Only breakpoints are returned; "dbstop if error" etc. are processed in the parser. * debug.cc (dbstop_process_map_ags, Fdbstop): set breakpoints etc. based on the output of A=dbstatus. The structure of A is not Matlab compatible. * debug.cc (do_add_breakpoint_1, do_get_breakpoint_list): Store file (not subfunction) names in bp_set, to avoid crash in "dbclear all". * debug.cc (dbclear_all_signals, condition_valid, stop_on_err_warn_status): New function * debug.cc (do_add_breakpoint): take "condition" parameter. * debug.cc (do_get_breakpoint_list): Make invariant copy of bp_set (bug #44195) * debug.cc (do_add_breakpoint, do_remove_breakpoint, do_remove_all_breakpoints_in_file): More informative error messages. * debug.cc (Fdbclear): clear break on signals (error, warning etc.) * debug.cc (Fdbstatus): Return all breakpoints when debugging, so that "s = dbstatus; ...; dbstop (s)" works. (Related to bug #41338, bug #41556) * debug.cc (Fdbstatus): Return structure with conditions, and "if error" etc. * debug.h (debug_on_err, debug_on_caught, debug_on_warn): New functions * debug.h: Rename "fname_line_map" to "fname_bp_map", as it has conditions * error.cc (verror): Allow dbstop on selected errors, or errors in try/catch * error.h New globals: Vdebug_on_caught, in_try_catch. * toplev.cc: Experimental code for Matlab's "dbstop if naninf". * symtab.cc (load_class_constructor): Add class constructors to list of methods so they can be breakpointed * pt-pb.{cc,h} (take_action): Add "condition" to set_breakpoint call, track bp_cond_list. * pt-eval.cc visit_.*_command: Ask if breakpoint condition is satisfied. * pt-eval.cc (visit_try_catch_command): Count the number of levels of try/catch we are in to allow "dbstop if caught error". * pt-stmt.cc (set_breakpoint): Pass condition * pt-stmt.cc (is_breakpoint): If new argument is true, only return true if the condition is set. * pt-stmt.cc (bp_cond, preakpoints_and_conds): new function * pt-stmt.h: new declarations * pt.{cc,h} (meets_bp_condition, bp_cond): New function * octave-link.h (update_breakpoint): Accept condition
author Lachlan Andrew <lachlanbis@gmail.com>
date Sun, 24 Jan 2016 11:02:30 +1100
parents e39e05d90788
children fcac5dbbf9ed
line wrap: on
line diff
--- a/libinterp/parse-tree/pt-stmt.cc	Sat Jan 30 08:22:36 2016 -0800
+++ b/libinterp/parse-tree/pt-stmt.cc	Sun Jan 24 11:02:30 2016 +1100
@@ -48,6 +48,8 @@
 #include "utils.h"
 #include "variables.h"
 
+#include "debug.h"
+
 // A list of commands to be executed.
 
 tree_statement::~tree_statement (void)
@@ -71,12 +73,12 @@
 }
 
 void
-tree_statement::set_breakpoint (void)
+tree_statement::set_breakpoint (const std::string& condition)
 {
   if (cmd)
-    cmd->set_breakpoint ();
+    cmd->set_breakpoint (condition);
   else if (expr)
-    expr->set_breakpoint ();
+    expr->set_breakpoint (condition);
 }
 
 void
@@ -89,9 +91,16 @@
 }
 
 bool
-tree_statement::is_breakpoint (void) const
+tree_statement::is_breakpoint (bool check_active) const
 {
-  return cmd ? cmd->is_breakpoint () : (expr ? expr->is_breakpoint () : false);
+  return cmd ? cmd->is_breakpoint (check_active)
+             : (expr ? expr->is_breakpoint (check_active) : false);
+}
+
+std::string
+tree_statement::bp_cond () const
+{
+  return cmd ? cmd->bp_cond () : (expr ? expr->bp_cond () : "0");
 }
 
 int
@@ -178,10 +187,12 @@
   tw.visit_statement (*this);
 }
 
+// Create a "breakpoint" tree-walker, and get it to "walk" this statement list
+// (TODO:  What does that do???)
 int
-tree_statement_list::set_breakpoint (int line)
+tree_statement_list::set_breakpoint (int line, const std::string& condition)
 {
-  tree_breakpoint tbp (line, tree_breakpoint::set);
+  tree_breakpoint tbp (line, tree_breakpoint::set, condition);
   accept (tbp);
 
   return tbp.get_line ();
@@ -218,9 +229,34 @@
   return tbp.get_list ();
 }
 
+// Get list of pairs (breakpoint line, breakpoint condition)
+std::list<bp_type>
+tree_statement_list::breakpoints_and_conds (void)
+{
+  tree_breakpoint tbp (0, tree_breakpoint::list);
+  accept (tbp);
+
+  std::list<bp_type> retval;
+  octave_value_list lines = tbp.get_list ();
+  octave_value_list conds = tbp.get_cond_list ();
+
+  for (int i = 0; i < lines.length (); i++)
+    {
+      retval.push_back (bp_type (lines(i).double_value (),
+                                conds(i).string_value ()));
+    }
+
+  return retval;
+}
+
+// Add breakpoints to  file  at multiple lines (the second arguments of  line),
+// to stop only if  condition  is true.
+// Updates GUI via  octave_link::update_breakpoint.
+// TODO COME BACK TO ME
 bp_table::intmap
 tree_statement_list::add_breakpoint (const std::string& file,
-                                     const bp_table::intmap& line)
+                                     const bp_table::intmap& line,
+                                     const std::string& condition)
 {
   bp_table::intmap retval;
 
@@ -234,10 +270,10 @@
         {
           int lineno = p->second;
 
-          retval[i] = set_breakpoint (lineno);
+          retval[i] = set_breakpoint (lineno, condition);
 
           if (retval[i] != 0 && ! file.empty ())
-            octave_link::update_breakpoint (true, file, retval[i]);
+            octave_link::update_breakpoint (true, file, retval[i], condition);
         }
     }