# HG changeset patch # User jwe # Date 1179800863 0 # Node ID bd0a70c3f2dbf95d3c7385e6180baf46f7824d2a # Parent 81eb28d50cee660e03279715f055638304c90bc3 [project @ 2007-05-22 02:27:43 by jwe] diff --git a/doc/ChangeLog b/doc/ChangeLog --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,7 @@ +2007-05-21 David Bateman + + * interpreter/debug.txi, io.txi, octave.txi: Doc fixes. + 2007-05-21 Søren Hauberg * interpreter/expr.txi: Describe +=, -=, *=, and /= operators. diff --git a/doc/interpreter/debug.txi b/doc/interpreter/debug.txi --- a/doc/interpreter/debug.txi +++ b/doc/interpreter/debug.txi @@ -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) diff --git a/doc/interpreter/io.txi b/doc/interpreter/io.txi --- a/doc/interpreter/io.txi +++ b/doc/interpreter/io.txi @@ -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 diff --git a/doc/interpreter/octave.texi b/doc/interpreter/octave.texi --- a/doc/interpreter/octave.texi +++ b/doc/interpreter/octave.texi @@ -333,6 +333,10 @@ Debugging +* Entering Debug Mode:: +* Breakpoints:: +* Debug Mode:: + Input and Output * Basic Input and Output:: diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2007-05-21 David Bateman + + * debug.cc (Fdbstop): handle integer, vector and multiple line + arguments. + (Fdbclar): ditto. Eliminate extraneous debugging messages. + 2007-05-21 Søren Hauberg * load-path.cc (Fpath, Frehash): Replace "LOADPATH" with "load diff --git a/src/debug.cc b/src/debug.cc --- a/src/debug.cc +++ b/src/debug.cc @@ -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 (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 (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, ,