octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Changeset] Re: Q: Low hanging fruit?


From: David Bateman
Subject: [Changeset] Re: Q: Low hanging fruit?
Date: Fri, 09 May 2008 13:13:48 +0200
User-agent: Thunderbird 2.0.0.12 (X11/20080306)

Bill Denney wrote:
> Out of curiosity, how could a user find them without knowing the
> functions are there already?  I can't find those functions with which,
> help, or iskeyword.  It seems like they should show up somehow
> (especially with help).  I could add them to the help documentation for
> keyboard, but that doesn't help too much if they don't have their own
> help pages.


Good point. There is nothing to stop these being easily documented with
DEFCMD functions in debug.cc though they are trapped in
 to makeinput.cc(get_user_input). However, if we do that it probably
makes sense them matlab compatible. The current behavior is that "dbstep
in" in matlab is the equivalent of "dbsrtep" in Octave, and "dbstep" in
matlab is teh equivalent of "dbnext" in Octave. Octave doesn't support
the "dbstep N" or "dbstep out" syntax.

The attached patch makes the dbstep command matlab compatible and adds
the dbquit command. However this change should be documented in the NEWS
file for 3.1 as it changes the behavior of the dbstep.

Regards
David
# HG changeset patch
# User David Bateman <address@hidden>
# Date 1210331185 -7200
# Node ID a938c18e7d24aea68ef4e2cb4c3859704fbd5271
# Parent  70677fe8882114bbd2ae9813ac36eb9a9ed6bdc5
Add dbquit and make dbstep compatible

diff --git a/src/ChangeLog b/src/ChangeLog
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,41 @@ 2008-05-06  David Bateman  <address@hidden
+2008-05-09  David Bateman  <address@hidden>
+
+       * debug.cc (Fdbstop): If no line specified assume line 1.
+       (Fdbstep, Fdbcont, Fdbquit): New functions documenting the
+       debugging functions.
+       * input.cc (static bool match_function(const std::string&, const
+       std::string&)): New function to find function names that might
+       have an argument.
+       (static std::string get_function_arg (const std::string&, const
+       std::string&)): New function to find the argument of a function 
+       names that might have an argument.
+       (get_user_input): Implement the dbquit command. Modify the dbstep
+       command for compatibility.
+       * pt-bp.h (MAYBE_DO_BREAKPOINT): Support break in n lines needed
+       to support "dbstep N". 
+       * pt.cc (tree::break_next): Convert to a down counter to support
+       break in N lines. Breakpoint occure when tree::break_next is zero.
+       * toplev.cc (octave_user_script *
+       octave_call_stack::do_caller_user_script (difference_type) const):
+       Support skipping the first N functions to support "dbstep out".
+       (octave_user_function * octave_call_stack::do_caller_user_function
+       (difference_type) const): Ditto.
+       (octave_user_code * octave_call_stack::do_caller_user_code
+       (difference_type) const): Ditto.
+       * toplev.h (octave_user_script *
+       octave_call_stack::do_caller_user_script (difference_type) const):
+       Add difference_type argument.
+       (octave_user_function * octave_call_stack::do_caller_user_function
+       (difference_type) const): Ditto.
+       (octave_user_code * octave_call_stack::do_caller_user_code
+       (difference_type) const): Ditto.
+       (static octave_user_script *caller_script (difference_type)):
+       Ditto.
+       (static octave_user_function *caller_user_function
+       (difference_type q)): Ditto.
+       (static octave_user_code *caller_user_code (difference_type q)):
+       Ditto.
+
 2008-05-06  David Bateman  <address@hidden>
 
        * ov-fcn-inline.cc (Finline): Also ignore NaN, Inf, pi, NA and eps.
diff --git a/src/debug.cc b/src/debug.cc
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -380,6 +380,9 @@ The rline returned is the real line that
 
   parse_dbfunction_params ("dbstop", args, symbol_name, lines);
 
+  if (lines.size () == 0)
+    lines[0] = 1;
+
   if (! error_state)
     retval = bp_table::add_breakpoint (symbol_name, lines);
 
@@ -833,6 +836,51 @@ If @var{n} is omitted, move down one fra
   return retval;
 }
 
+DEFCMD (dbstep, , ,
+  "-*- texinfo -*-\n\
address@hidden {Command} {} dbstep @var{n}\n\
address@hidden {Command} {} dbstep in\n\
address@hidden {Command} {} dbstep out\n\
+In debugging mode, execute the next @var{n} lines of code. If @var{n} is\n\
+omitted execute the next line of code. If the next line of code is itself\n\
+defined in terms of an m-file remain in the existing function.\n\
+\n\
+Using @code{dbstep in} will cause execution of the next line to step into\n\
+any m-files defined on the next line. Using @code{dbstep out} with cause\n\
+execution to continue until the current function returns.\n\
address@hidden, dbquit}\n\
address@hidden deftypefn")
+{
+  error ("dbstep: can only be called in debug mode");
+
+  return octave_value ();
+}
+
+DEFCMD (dbcont, args, ,
+  "-*- texinfo -*-\n\
address@hidden {Command} {} dbcont ()\n\
+In debugging mode, quit debugging mode and continue execution.\n\
address@hidden, dbstep}\n\
address@hidden deftypefn")
+{
+  error ("dbcont: can only be called in debug mode");
+
+  return octave_value ();
+}
+
+DEFCMD (dbquit, args, ,
+  "-*- texinfo -*-\n\
address@hidden {Command} {} dbquit ()\n\
+In debugging mode, quit debugging mode and return to the top level.\n\
address@hidden, dbcont}\n\
address@hidden deftypefn")
+{
+  error ("dbquit: can only be called in debug mode");
+
+  return octave_value ();
+}
+
+
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
diff --git a/src/input.cc b/src/input.cc
--- a/src/input.cc
+++ b/src/input.cc
@@ -583,6 +583,34 @@ match_sans_spaces_semi (const std::strin
   return false;
 }
 
+static bool
+match_function (const std::string& standard, const std::string& test)
+{
+  size_t beg = test.find_first_not_of (" \t");
+
+  if (beg != NPOS)
+    return (test.substr (beg, standard.length ()) == standard);
+
+  return false;
+}
+
+static std::string
+get_function_arg (const std::string& standard, const std::string& test)
+{
+  size_t beg = test.find_first_not_of (" \t") + standard.length ();
+  if (beg == NPOS)
+    return std::string();
+  beg = test.find_first_not_of (" \t(\"\'", beg);
+  if (beg == NPOS)
+    return std::string();
+  size_t end = test.find_first_of (" \t\"\');");
+
+  if (end == NPOS)
+    return test.substr (beg);
+  else
+    return test.substr (beg, end);
+}
+
 // If the user simply hits return, this will produce an empty matrix.
 
 static octave_value_list
@@ -689,19 +717,58 @@ get_user_input (const octave_value_list&
            {
              return retval;
            }
-         else if (match_sans_spaces_semi ("dbstep", input_buf))
+         else if (match_sans_spaces_semi ("dbquit", input_buf))
+           octave_throw_interrupt_exception ();
+         else if (match_function ("dbstep", input_buf))
            {
-             tree::break_next = true;
-
-             tree::last_line = 0;
-
-             tree::break_function = octave_call_stack::current ();
-
-             return retval;
+             std::string arg = get_function_arg ("dbstep", input_buf);
+
+             if (arg == "in")
+               {
+                 tree::break_next = 0;
+
+                 tree::last_line = 0;
+
+                 tree::break_function = octave_call_stack::current ();
+
+                 return retval;
+               }
+             else if (arg == "out")
+               {
+                 tree::break_next = 0;
+
+                 tree::last_line = -1;
+
+                 tree::break_function = octave_call_stack::caller_user_code 
(1);
+
+                 return retval;
+               }
+             else
+               {
+                 tree::break_next = 0;
+
+                 if (arg.length () != 0)
+                   {
+                     if (isdigit (arg.at(0)))
+                       tree::break_next = atoi (arg.c_str ());
+                     else
+                       {
+                         error ("dbstep: invalid argument");
+
+                         goto again;
+                       }
+                   }
+
+                 tree::last_line = octave_call_stack::current_line ();
+                 
+                 tree::break_function = octave_call_stack::current ();
+
+                 return retval;
+               }
            }
          else if (match_sans_spaces_semi ("dbnext", input_buf))
            {
-             tree::break_next = true;
+             tree::break_next = 0;;
 
              tree::last_line = octave_call_stack::current_line ();
 
diff --git a/src/pt-bp.h b/src/pt-bp.h
--- a/src/pt-bp.h
+++ b/src/pt-bp.h
@@ -166,31 +166,40 @@ extern bool octave_debug_on_interrupt_st
       octave_function *xfcn = octave_call_stack::current (); \
  \
       if (octave_debug_on_interrupt_state \
-         || (tree::break_next && tree::last_line == 0) \
-         || (tree::break_next \
+         || (tree::break_next >= 0 && tree::last_line == 0) \
+         || (tree::break_next >= 0 \
              && xfcn == tree::break_function \
              && tree::last_line != line ()) \
          || is_breakpoint ()) \
         { \
-          octave_debug_on_interrupt_state = false; \
- \
-          tree::break_next = false; \
- \
-          if (xfcn) \
-            octave_stdout << xfcn->name () << ": ";  \
- \
-          octave_stdout << "line " << line () << ", " \
-                       << "column " << column () \
-                       << std::endl; \
- \
-          tree_print_code tpc (octave_stdout); \
-          this->accept (tpc); \
- \
-          octave_stdout << std::endl; \
- \
-          tree::break_statement = this; \
- \
-          do_keyboard (); \
+         if (!octave_debug_on_interrupt_state && tree::break_next > 0) \
+           { \
+             tree::break_next--; \
+             if (tree::last_line > 0) \
+               tree::last_line = line(); \
+           } \
+         else \
+           { \
+              octave_debug_on_interrupt_state = false; \
+ \
+              tree::break_next = -1; \
+ \
+              if (xfcn) \
+                octave_stdout << xfcn->name () << ": ";  \
+ \
+              octave_stdout << "line " << line () << ", " \
+                           << "column " << column () \
+                           << std::endl; \
+ \
+              tree_print_code tpc (octave_stdout); \
+              this->accept (tpc); \
+ \
+              octave_stdout << std::endl; \
+ \
+              tree::break_statement = this; \
+ \
+              do_keyboard (); \
+           } \
         } \
     } \
   while (0)
diff --git a/src/pt.cc b/src/pt.cc
--- a/src/pt.cc
+++ b/src/pt.cc
@@ -33,8 +33,8 @@ along with Octave; see the file COPYING.
 #include "pt.h"
 #include "pt-pr-code.h"
 
-// If true, stop executing at the next possible point.
-bool tree::break_next = false;
+// If zero, stop executing at the next possible point.
+int tree::break_next = -1;
 
 // The line where dbnext was executed.
 int tree::last_line = 0;
diff --git a/src/pt.h b/src/pt.h
--- a/src/pt.h
+++ b/src/pt.h
@@ -66,7 +66,7 @@ public:
     { return break_point; }
 
   // If true, stop executing at the next possible point.
-  static bool break_next;
+  static int break_next;
   
   // The line where dbnext was executed.
   static int last_line; 
diff --git a/src/toplev.cc b/src/toplev.cc
--- a/src/toplev.cc
+++ b/src/toplev.cc
@@ -112,11 +112,11 @@ octave_call_stack::do_current_column (vo
 }
 
 octave_user_script *
-octave_call_stack::do_caller_user_script (void) const
+octave_call_stack::do_caller_user_script (difference_type q) const
 {
   octave_user_script *retval = 0;
 
-  for (const_iterator p = cs.begin (); p != cs.end (); p++)
+  for (const_iterator p = cs.begin () + q; p != cs.end (); p++)
     {
       const call_stack_elt& elt = *p;
 
@@ -133,11 +133,11 @@ octave_call_stack::do_caller_user_script
 }
 
 octave_user_function *
-octave_call_stack::do_caller_user_function (void) const
+octave_call_stack::do_caller_user_function (difference_type q) const
 {
   octave_user_function *retval = 0;
 
-  for (const_iterator p = cs.begin (); p != cs.end (); p++)
+  for (const_iterator p = cs.begin () + q; p != cs.end (); p++)
     {
       const call_stack_elt& elt = *p;
 
@@ -154,11 +154,11 @@ octave_call_stack::do_caller_user_functi
 }
 
 octave_user_code *
-octave_call_stack::do_caller_user_code (void) const
+octave_call_stack::do_caller_user_code (difference_type q) const
 {
   octave_user_code *retval = 0;
 
-  for (const_iterator p = cs.begin (); p != cs.end (); p++)
+  for (const_iterator p = cs.begin () + q; p != cs.end (); p++)
     {
       const call_stack_elt& elt = *p;
 
diff --git a/src/toplev.h b/src/toplev.h
--- a/src/toplev.h
+++ b/src/toplev.h
@@ -94,6 +94,7 @@ public:
 
   typedef std::deque<call_stack_elt>::iterator iterator;
   typedef std::deque<call_stack_elt>::const_iterator const_iterator;
+  typedef std::deque<call_stack_elt>::difference_type difference_type;
 
   static bool instance_ok (void)
   {
@@ -149,21 +150,21 @@ public:
   }
   
   // First script on the stack.
-  static octave_user_script *caller_script (void)
-  {
-    return instance_ok () ? instance->do_caller_user_script () : 0;
+  static octave_user_script *caller_script (difference_type q = 0)
+  {
+    return instance_ok () ? instance->do_caller_user_script (q) : 0;
   }
 
   // First user-defined function on the stack.
-  static octave_user_function *caller_user_function (void)
-  {
-    return instance_ok () ? instance->do_caller_user_function () : 0;
+  static octave_user_function *caller_user_function (difference_type q = 0)
+  {
+    return instance_ok () ? instance->do_caller_user_function (q) : 0;
   }
 
   // First user-defined function on the stack.
-  static octave_user_code *caller_user_code (void)
-  {
-    return instance_ok () ? instance->do_caller_user_code () : 0;
+  static octave_user_code *caller_user_code (difference_type q = 0)
+  {
+    return instance_ok () ? instance->do_caller_user_code (q) : 0;
   }
 
   static void
@@ -251,11 +252,11 @@ private:
     return retval;
   }
 
-  octave_user_script *do_caller_user_script (void) const;
-
-  octave_user_function *do_caller_user_function (void) const;
-
-  octave_user_code *do_caller_user_code (void) const;
+  octave_user_script *do_caller_user_script (difference_type q = 0) const;
+
+  octave_user_function *do_caller_user_function (difference_type q = 0) const;
+
+  octave_user_code *do_caller_user_code (difference_type q = 0) const; 
 
   void do_push (octave_function *f, symbol_table::scope_id scope,
                symbol_table::context_id context)

reply via email to

[Prev in Thread] Current Thread [Next in Thread]