changeset 26954:6e50f1fedeb5

dbstop: accept "at CLASS in METHOD" syntax (partial fix for bug #45404) * bp-table.h, bp-table.cc (bp_table::parse_dbfunction_params): New parameter CLASS_NAME. Attempt to accept "at CLASS in METHOD" syntax. Change all uses. * debug.cc (Fdbstop): Update docstring.
author John W. Eaton <jwe@octave.org>
date Wed, 20 Mar 2019 18:57:23 +0000
parents 6e01e5be8de3
children 9e2f69c1a05d
files libinterp/corefcn/debug.cc libinterp/parse-tree/bp-table.cc libinterp/parse-tree/bp-table.h
diffstat 3 files changed, 46 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/debug.cc	Wed Mar 20 11:24:07 2019 -0700
+++ b/libinterp/corefcn/debug.cc	Wed Mar 20 18:57:23 2019 +0000
@@ -90,10 +90,13 @@
 @deftypefnx {} {} dbstop in @var{func}
 @deftypefnx {} {} dbstop in @var{func} at @var{line}
 @deftypefnx {} {} dbstop in @var{func} at @var{line} if "@var{condition}"
+@deftypefnx {} {} dbstop in @var{class} at @var{method}
 @deftypefnx {} {} dbstop if @var{event}
 @deftypefnx {} {} dbstop if @var{event} @var{ID}
 @deftypefnx {} {} dbstop (@var{bp_struct})
 @deftypefnx {} {@var{rline} =} dbstop @dots{}
+dbstop in waveClass at waveClass.plotEta
+dbstop waveClass at waveClass.plotEta
 
 Set breakpoints for the built-in debugger.
 
@@ -173,6 +176,7 @@
 {
   octave::bp_table::intmap retmap;
   std::string symbol_name = "";  // stays empty for "dbstop if error" etc
+  std::string class_name = "";
   octave::bp_table::intmap lines;
   std::string condition = "";
   octave_value retval;
@@ -185,7 +189,7 @@
     {
       // explicit function / line / condition
       bptab.parse_dbfunction_params ("dbstop", args, symbol_name,
-                                     lines, condition);
+                                     class_name, lines, condition);
 
       if (lines.size () == 0)
         lines[0] = 1;
@@ -300,6 +304,7 @@
 @end deftypefn */)
 {
   std::string symbol_name = "";  // stays empty for "dbclear if error" etc
+  std::string class_name = "";
   octave::bp_table::intmap lines;
   std::string dummy;             // "if" condition -- only used for dbstop
 
@@ -309,7 +314,7 @@
 
   octave::bp_table& bptab = tw.get_bp_table ();
 
-  bptab.parse_dbfunction_params ("dbclear", args, symbol_name, lines, dummy);
+  bptab.parse_dbfunction_params ("dbclear", args, symbol_name, class_name, lines, dummy);
 
   if (nargin == 1 && symbol_name == "all")
     {
--- a/libinterp/parse-tree/bp-table.cc	Wed Mar 20 11:24:07 2019 -0700
+++ b/libinterp/parse-tree/bp-table.cc	Wed Mar 20 18:57:23 2019 +0000
@@ -252,22 +252,29 @@
     dbstop_none
   };
 
+  // FIXME: This function probalby needs to be completely overhauled to
+  // correctly parse the full syntax of the dbstop command and properly
+  // reject incorrect forms.
+
   // Parse parameters (args) of dbstop and dbclear commands.
   // For dbstop, who=="dbstop"; for dbclear, who=="dbclear".
-  // The syntax is: dbstop [[in] symbol] [[at] line [line [...]]] [if condition]
+  // The syntax is: dbstop [[in] symbol] [[at] [method | line [line [...]]]] [if condition]
   // where the form of condition depends on whether or not a file or line has
-  // been seen.
+  // been seen.  IF symbol and method are specified, then symbol should
+  // be a class name.  Otherwise it should be a function name.
   // Also execute "if [error|warning|interrupt|naninf]" clauses.
 
   void bp_table::parse_dbfunction_params (const char *who,
                                           const octave_value_list& args,
-                                          std::string& symbol_name,
+                                          std::string& func_name,
+                                          std::string& class_name,
                                           bp_table::intmap& lines,
                                           std::string& cond)
   {
     int nargin = args.length ();
     int list_idx = 0;
-    symbol_name = "";
+    func_name = "";
+    class_name = "";
     lines = bp_table::intmap ();
 
     if (nargin == 0 || ! args(0).is_string ())
@@ -317,10 +324,10 @@
         switch (tok)
           {
           case dbstop_in:
-            symbol_name = args(pos).string_value ();
+            func_name = args(pos).string_value ();
             if (seen_in)
               error ("%s: Too many function names specified -- %s",
-                     who, symbol_name.c_str ());
+                     who, func_name.c_str ());
             else if (seen_at || seen_if)
               error ("%s: function name must come before line number and 'if'",
                      who);
@@ -336,18 +343,36 @@
               error ("%s: line number must come before 'if' clause\n", who);
             seen_at = true;
 
-            if (! seen_in)
+            if (seen_if)
+              error ("%s: line number must come before 'if' clause\n", who);
+            else if (seen_in)
+              {
+                std::string arg = args(pos).string_value ();
+
+                // FIXME: we really want to distinguish number
+                // vs. method name here.
+
+                if (atoi (arg.c_str ()) == 0)
+                  {
+                    // We have class and function names but already
+                    // stored the class name in func_name.
+                    class_name = func_name;
+                    func_name = arg;
+                    pos++;
+                    break;
+                  }
+
+              }
+            else
               {
                 // It was a line number.  Get function name from debugger.
                 if (Vdebugging)
-                  symbol_name = m_evaluator.get_user_code ()->profiler_name ();
+                  func_name = m_evaluator.get_user_code ()->profiler_name ();
                 else
                   error ("%s: function name must come before line number "
                          "and 'if'", who);
                 seen_in = true;
               }
-            else if (seen_if)
-              error ("%s: line number must come before 'if' clause\n", who);
 
             // Read a list of line numbers (or arrays thereof)
             for ( ; pos < nargin; pos++)
@@ -359,7 +384,7 @@
                     if (line > 0)
                       lines[list_idx++] = line;
                     else
-                      break;        // may be "if"
+                      break;        // may be "if" or a method name
                   }
                 else if (args(pos).isnumeric ())
                   {
--- a/libinterp/parse-tree/bp-table.h	Wed Mar 20 11:24:07 2019 -0700
+++ b/libinterp/parse-tree/bp-table.h	Wed Mar 20 18:57:23 2019 +0000
@@ -121,9 +121,9 @@
 
     bool condition_valid (const std::string& cond);
 
-    void parse_dbfunction_params (const char *, const octave_value_list&,
-                                  std::string&, bp_table::intmap&,
-                                  std::string&);
+    void parse_dbfunction_params (const char *who, const octave_value_list& args,
+                                  std::string& func_name, std::string& class_name,
+                                  bp_table::intmap& lines, std::string& cond);
 
   private: