changeset 6646:bd0a70c3f2db

[project @ 2007-05-22 02:27:43 by jwe]
author jwe
date Tue, 22 May 2007 02:27:43 +0000
parents 81eb28d50cee
children 415b8b0106d0
files doc/ChangeLog doc/interpreter/debug.txi doc/interpreter/io.txi doc/interpreter/octave.texi src/ChangeLog src/debug.cc
diffstat 6 files changed, 226 insertions(+), 83 deletions(-) [+]
line wrap: on
line diff
--- a/doc/ChangeLog	Mon May 21 21:05:54 2007 +0000
+++ b/doc/ChangeLog	Tue May 22 02:27:43 2007 +0000
@@ -1,3 +1,7 @@
+2007-05-21  David Bateman  <dbatemna@free.fr>
+
+	* interpreter/debug.txi, io.txi, octave.txi: Doc fixes.
+
 2007-05-21  Søren Hauberg  <hauberg@gmail.com>
 
         * interpreter/expr.txi: Describe +=, -=, *=, and /= operators.
--- a/doc/interpreter/debug.txi	Mon May 21 21:05:54 2007 +0000
+++ b/doc/interpreter/debug.txi	Tue May 22 02:27:43 2007 +0000
@@ -5,18 +5,114 @@
 @node Debugging
 @chapter Debugging
 
-@DOCSTRING(dbstop)
+Octave includes a built-in debugger to aid in the development of
+scripts. This can be used to interrupt the execution of an Octave script
+at a certain point, or when certain conditions are met. Once execution
+has stopped, and debug mode is entered, the symbol table at the point
+where execution has stopped can be examined and modified to check for
+errors.
 
-@DOCSTRING(dbclear)
+The normal commandline editing and history functions are available in
+debug mode. However, one limitation on the debug mode is that
+commands entered at the debug prompt are evaluated as strings, rather
+than being handled by the Octave parser. This means that all commands in
+debug mode must be contained on a single line. That is, it is alright to
+write
+
+@example
+debug> for i = 1:n, foo(i); endfor
+@end example
 
-@DOCSTRING(dbstatus)
+@noindent
+in debug mode. However, writing the above in three lines will not be
+correctly evaluated. To leave the debug mode, you should simply type
+either @code{quit} or @code{exit}.
+
+@menu
+* Entering Debug Mode::
+* Breakpoints::
+* Debug Mode::
+@end menu
 
-@DOCSTRING(dbwhere)
+@node Entering Debug Mode
+@section Entering Debug Mode
 
-@DOCSTRING(dbtype)
+There are two basic means of interrupting the execution of an Octave
+script. These are breakpoints @ref{Breakpoints}, discussed in the next
+section and interruption based on some condition.
+
+Octave supports three means to stop execution based on the values set in
+the functions @code{debug_on_interrupt}, @code{debug_on_warning} and
+@code{debug_on_error}.
 
 @DOCSTRING(debug_on_interrupt)
 
 @DOCSTRING(debug_on_warning)
 
 @DOCSTRING(debug_on_error)
+
+@node Breakpoints
+@section Breakpoints
+
+Breakpoints can be set in any Octave function, using the @code{dbstop}
+function.
+
+@DOCSTRING(dbstop)
+
+@noindent
+Note that breakpoints can not be set in built-in functions
+(eg. @code{sin}, etc) or dynamically loaded function (ie. oct-files). To
+set a breakpoint immediately on entering a function, the breakpoint
+should be set to line 1. The leading comment block will be ignored and
+the breakpoint will be set to the first executable statement in the
+function. For example
+
+@example
+@group
+dbstop ("asind", 1)
+@result{} 27
+@end group
+@end example
+
+@noindent
+Note that the return value of @code{27} means that the breakpoint was
+effectively set to line 27. The status of breakpoints in a function can
+be queried with the @code{dbstatus} function.
+
+@DOCSTRING(dbstatus)
+
+@noindent
+Taking the above as an example, @code{dbstatus ("asind")} should return
+27. The breakpoints can then be cleared with the @code{dbclear} function
+
+@DOCSTRING(dbclear)
+
+@noindent
+To clear all of the breakpoints in a function the recommended means,
+following the above example, is then
+
+@example
+dbclear ("asind", dbstatus ("asind"));
+@end example
+
+Another simple means of setting a breakpoint in an Octave script is the
+use of the @code{keyboard} function.
+
+@DOCSTRING(keyboard)
+
+@noindent
+The @code{keyboard} function is typically placed in a script at the
+point where the user desires that the execution is stopped. It
+automatically sets the running script into the debug mode.
+
+@node Debug Mode
+@section Debug Mode
+
+There are two additional support functions that allow the user to
+interrogate where in the execution of a script Octave entered the debug
+mode and to print the code in the script surrounding the point where
+Octave entered debug mode.
+
+@DOCSTRING(dbwhere)
+
+@DOCSTRING(dbtype)
--- a/doc/interpreter/io.txi	Mon May 21 21:05:54 2007 +0000
+++ b/doc/interpreter/io.txi	Tue May 22 02:27:43 2007 +0000
@@ -101,10 +101,8 @@
 
 @DOCSTRING(menu)
 
-@DOCSTRING(keyboard)
-
-For both @code{input} and @code{keyboard}, the normal command line
-history and editing functions are available at the prompt.
+For @code{input}, the normal command line history and editing functions
+are available at the prompt.
 
 Octave also has a function that makes it possible to get a single
 character from the keyboard without requiring the user to type a
--- a/doc/interpreter/octave.texi	Mon May 21 21:05:54 2007 +0000
+++ b/doc/interpreter/octave.texi	Tue May 22 02:27:43 2007 +0000
@@ -333,6 +333,10 @@
 
 Debugging
 
+* Entering Debug Mode::
+* Breakpoints::
+* Debug Mode::
+
 Input and Output
 
 * Basic Input and Output::      
--- a/src/ChangeLog	Mon May 21 21:05:54 2007 +0000
+++ b/src/ChangeLog	Tue May 22 02:27:43 2007 +0000
@@ -1,3 +1,9 @@
+2007-05-21  David Bateman  <dbateman@free.fr>
+
+	* debug.cc (Fdbstop): handle integer, vector and multiple line
+	arguments.
+	(Fdbclar): ditto. Eliminate extraneous debugging messages.
+
 2007-05-21  Søren Hauberg  <hauberg@gmail.com>
 
         * load-path.cc (Fpath, Frehash): Replace "LOADPATH" with "load
--- a/src/debug.cc	Mon May 21 21:05:54 2007 +0000
+++ b/src/debug.cc	Tue May 22 02:27:43 2007 +0000
@@ -87,14 +87,15 @@
 
 DEFCMD (dbstop, args, ,
   "-*- texinfo -*-\n\
-@deftypefn {Loadable Function} {rline =} dbstop (func, line)\n\
+@deftypefn {Loadable Function} {rline =} dbstop (func, line, @dots{})\n\
 Set a breakpoint in a function\n\
 @table @code\n\
 @item func\n\
 String representing the function name.  When already in debug\n\
 mode this should be left out and only the line should be given.\n\
 @item line\n\
-Line you would like the breakpoint to be set on\n\
+Line you would like the breakpoint to be set on. Multiple\n\
+lines might be given as seperate arguments or as a vector.\n\
 @end table\n\
 \n\
 The rline returned is the real line that the breakpoint was set at.\n\
@@ -102,118 +103,152 @@
 @end deftypefn")
 {
   octave_value retval;
-
-  int result = -1;
   int nargin = args.length ();
+  int idx = 0;
+  std::string symbol_name = "";
 
-  string_vector argv = args.make_argv ("dbstop");
-
-  if (error_state)
-    return retval;
+  if (nargin != 1 && args(0).is_string())
+    {
+      symbol_name = args(0).string_value ();
+      idx = 1;
+    }
 
-  if (nargin == 2)
-    {
-      std::string symbol_name = argv[1];
-
-      std::string line_number = argv[2];
+  octave_user_function *dbg_fcn = get_user_function (symbol_name);
 
-      int line = atoi (line_number.c_str ());
+  if (dbg_fcn)
+    {
+      octave_idx_type nsize = 10;
+      RowVector results (nsize);
+      octave_idx_type nr = 0;
 
-      octave_user_function *dbg_fcn = get_user_function (symbol_name);
+      tree_statement_list *cmds = dbg_fcn->body ();
 
-      if (dbg_fcn)
+      for (int i = idx; i < nargin; i++)
 	{
-	  tree_statement_list *cmds = dbg_fcn->body ();
-	  result = cmds->set_breakpoint (line);
-	}
-      else
-	error ("dbstop: unable to find the function requested\n");
-    }
-  else if (nargin == 1)
-    {
-      std::string line_number = argv[1];
+	  if (args(i).is_string ())
+	    {
+	      int line = atoi (args(i).string_value ().c_str ());
+
+	      if (error_state)
+		break;
+
+	      if (nr == nsize)
+		{
+		  nsize *= 2;
+		  results.resize (nsize);
+		}
+
+	      results(nr++) = cmds->set_breakpoint (line);
+	    }
+	  else
+	    {
+	      const NDArray arg = args(i).array_value ();
+
+	      if (error_state)
+		break;
 
-      int line = atoi (line_number.c_str ());
+	      for (octave_idx_type j = 0; j < arg.nelem(); j++)
+		{
+		  int line = static_cast<int> (arg.elem (j));
+
+		  if (error_state)
+		    break;
 
-      octave_user_function *dbg_fcn = get_user_function ();
+		  if (nr == nsize)
+		    {
+		      nsize *= 2;
+		      results.resize (nsize);
+		    }
 
-      if (dbg_fcn)
+		  results(nr++) = cmds->set_breakpoint (line);
+		}
+
+	      if (error_state)
+		break;
+	    }
+	}
+
+      if (! error_state)
 	{
-	  tree_statement_list *cmds = dbg_fcn->body ();
-	  result = cmds->set_breakpoint (line);
+	  results.resize (nr);
+	  retval = results;
 	}
-      else
-	error ("dbstop: unable to find the function requested\n");	
     }
   else
-    error ("dbstop: one argument when in a function and two when not\n");
-
-  retval = result;
+    error ("dbstop: unable to find the function requested\n");
 
   return retval;
 }
 
 DEFCMD (dbclear, args, ,
   "-*- texinfo -*-\n\
-@deftypefn {Loadable Function} {} dbclear (func, line)\n\
+@deftypefn {Loadable Function} {} dbclear (func, line, @dots{})\n\
 Delete a breakpoint in a function\n\
 @table @code\n\
 @item func\n\
 String representing the function name.  When already in debug\n\
 mode this should be left out and only the line should be given.\n\
 @item line\n\
-Line where you would like to remove the the breakpoint\n\
+Line where you would like to remove the the breakpoint. Multiple\n\
+lines might be given as seperate arguments or as a vector.\n\
 @end table\n\
 No checking is done to make sure that the line you requested is really\n\
-a breakpoint.   If you get the wrong line nothing will happen.\n\
+a breakpoint. If you get the wrong line nothing will happen.\n\
 @seealso{dbstop, dbstatus, dbwhere}\n\
 @end deftypefn")
 {
   octave_value retval;
-
+  int nargin = args.length ();
+  int idx = 0;
   std::string symbol_name = "";
-  std::string line_number;
+
+  if (nargin != 1 && args(0).is_string())
+    {
+      symbol_name = args(0).string_value ();
+      idx = 1;
+    }
 
-  int line = -1;
-  int nargin = args.length ();
+  octave_user_function *dbg_fcn = get_user_function (symbol_name);
+
+  if (dbg_fcn)
+    {
+      tree_statement_list *cmds = dbg_fcn->body ();
 
-  string_vector argv = args.make_argv ("dbclear");
+      for (int i = idx; i < nargin; i++)
+	{
+	  if (args(i).is_string ())
+	    {
+	      int line = atoi (args(i).string_value ().c_str ());
 
-  if (error_state)
-    return retval;
+	      if (error_state)
+		break;
+
+	      cmds->delete_breakpoint (line);
+	    }
+	  else
+	    {
+	      const NDArray arg = args(i).array_value ();
+
+	      if (error_state)
+		break;
 
-  if (nargin == 1 || nargin == 2)
-    {
-      if (nargin == 2)
-	{
-	  symbol_name = argv[1];
+	      for (octave_idx_type j = 0; j < arg.nelem (); j++)
+		{
+		  int line = static_cast<int> (arg.elem (j));
+
+		  if (error_state)
+		    break;
 
-	  octave_stdout << argv[1] << std::endl;
-	  line_number = argv[2];
+		  cmds->delete_breakpoint (line);
+		}
+
+	      if (error_state)
+		break;
+	    }
 	}
-      else if (nargin == 1)
-	{
-	  line_number = argv[1];
-	}
-
-      if (line_number.compare ("all") && line_number.compare ("ALL"))
-	line = atoi (line_number.c_str ());
-      else
-	line = -1;
-
-      octave_stdout << "symbol_name = " << symbol_name << std::endl;
-      octave_user_function *dbg_fcn = get_user_function (symbol_name);
-
-      if (dbg_fcn)
-	{
-	  tree_statement_list *cmds = dbg_fcn->body ();
-	  cmds->delete_breakpoint (line);
-	}
-      else
-	error ("dbclear: unable to find the function requested\n");
     }
   else
-    error ("dbclear: expecting one or two arguements\n");
+    error ("dbclear: unable to find the function requested\n");
 
   return retval;
 }
@@ -350,7 +385,7 @@
   else
     os << "dbtype: unknown function " << name << "\n";
 
-  os.flush();
+  os.flush ();
 }
 
 DEFCMD (dbtype, args, ,