# HG changeset patch # User jwe # Date 1193793852 0 # Node ID ac7179f00422d96cf1f93cdd5b9a5da3f044a18f # Parent 503001863427f68a82e2d7b6d0b940243eebc87e [project @ 2007-10-31 01:24:12 by jwe] diff -r 503001863427 -r ac7179f00422 src/ChangeLog --- a/src/ChangeLog Wed Oct 31 01:09:28 2007 +0000 +++ b/src/ChangeLog Wed Oct 31 01:24:12 2007 +0000 @@ -1,3 +1,15 @@ +2007-10-30 John Swensen + + * debug.h: New file. + * debug.cc (parse_dbfunction_params, do_find_bkpt_list, + intmap_to_ov): New functions. + (Fdbstop, Fdbclear): Use parse_dbfunction_params. + Improve compatibility. + (Fdbstatus): Improve compatibility. + + * help.cc (do_which): No longer static. + * help.h: Provide decl. + 2007-10-30 David Bateman * symtab.cc: Doc fixes for small book format. diff -r 503001863427 -r ac7179f00422 src/debug.cc --- a/src/debug.cc Wed Oct 31 01:09:28 2007 +0000 +++ b/src/debug.cc Wed Oct 31 01:24:12 2007 +0000 @@ -19,7 +19,6 @@ . */ - #ifdef HAVE_CONFIG_H #include #endif @@ -27,9 +26,12 @@ #include #include #include +#include + #include "defun.h" #include "error.h" +#include "help.h" #include "input.h" #include "pager.h" #include "oct-obj.h" @@ -40,6 +42,8 @@ #include "ov.h" #include "ov-usr-fcn.h" #include "ov-fcn.h" +#include "ov-list.h" +#include "ov-struct.h" #include "pt-pr-code.h" #include "pt.h" #include "pt-bp.h" @@ -48,12 +52,16 @@ #include "unwind-prot.h" #include "variables.h" +#include "debug.h" + +// Initialize the singleton object +bp_table *bp_table::instance = NULL; + // Return a pointer to the user-defined function FNAME. If FNAME is // empty, search backward for the first user-defined function in the // current call stack. - static octave_user_function * -get_user_function (std::string fname = "") +get_user_function (const std::string& fname = "") { octave_user_function *dbg_fcn = 0; @@ -71,7 +79,6 @@ else { ptr = lookup_by_name (fname, false); - if (ptr && ptr->is_user_function ()) { octave_value tmp = ptr->def (); @@ -83,6 +90,248 @@ return dbg_fcn; } +static void +parse_dbfunction_params (const octave_value_list& args, + std::string& symbol_name, + intmap& lines) +{ + octave_idx_type len = 0; + int nargin = args.length (); + int idx = 0; + int list_idx = 0; + symbol_name = std::string (); + + // If we are already in a debugging function + if (octave_call_stack::caller_user_function () != NULL) + { + idx = 0; + } + else + { + symbol_name = args (0).string_value (); + if (error_state) + return; + idx = 1; + } + + for (int i = idx; i < nargin; i++ ) + { + if (args (i).is_string ()) + len += 1; + else + len += args (i).numel (); + } + + lines = intmap(); + for (int i = idx; i < nargin; i++ ) + { + if (args (i).is_string ()) + { + int line = atoi (args (i).string_value ().c_str ()); + if (error_state) + break; + lines[list_idx++] = line; + } + else + { + const NDArray arg = args (i).array_value (); + + if (error_state) + break; + + for (octave_idx_type j = 0; j < arg.nelem(); j++) + { + int line = static_cast (arg.elem (j)); + if (error_state) + break; + lines[list_idx++] = line; + } + + if (error_state) + break; + } + } +} + +intmap +bp_table::add_breakpoint (const std::string& fname, + const intmap& line) +{ + if (!instance_ok ()) + return intmap(); + + octave_idx_type len = line.size (); + intmap retval; + octave_user_function *dbg_fcn = get_user_function (fname); + + if (dbg_fcn) + { + tree_statement_list *cmds = dbg_fcn->body (); + for (int i = 0; i < len; i++) + { + intmap::const_iterator p = line.find (i); + if (p != line.end ()) + { + int lineno = p->second; + retval[i] = cmds->set_breakpoint (lineno); + if (retval[i] != 0) + instance->bp_map[fname] = dbg_fcn; + } + } + } + else + error ("add_breakpoint: unable to find the function requested\n"); + + return retval; +} + + +int +bp_table::remove_breakpoint (const std::string& fname, + const intmap& line) +{ + if (!instance_ok ()) + return 0; + + octave_idx_type len = line.size (); + int retval = 0; + + if (len == 0) + { + intmap results = remove_all_breakpoints_in_file (fname); + retval = results.size (); + } + else + { + octave_user_function *dbg_fcn = get_user_function (fname); + if (dbg_fcn) + { + tree_statement_list *cmds = dbg_fcn->body (); + for (int i = 0; i < len; i++) + { + intmap::const_iterator p = line.find (i); + if (p != line.end ()) + { + int lineno = p->second; + cmds->delete_breakpoint (lineno); + } + } + octave_value_list results = cmds->list_breakpoints (); + if (results.length () == 0) + instance->bp_map.erase (instance->bp_map.find (fname)); + retval = results.length (); + } + else + error ("remove_breakpoint: unable to find the function requested\n"); + } + return retval; +} + + +intmap +bp_table::remove_all_breakpoints_in_file (const std::string& fname) +{ + if (!instance_ok ()) + return intmap(); + + octave_value_list bkpts; + intmap retval; + octave_user_function *dbg_fcn = get_user_function (fname); + + if (dbg_fcn) + { + tree_statement_list *cmds = dbg_fcn->body (); + bkpts = cmds->list_breakpoints (); + for (int i = 0; i < bkpts.length (); i++) + { + int lineno = static_cast (bkpts (i).int_value ()); + cmds->delete_breakpoint (lineno); + retval[i] = lineno; + } + instance->bp_map.erase (instance->bp_map.find (fname)); + } + else + error ("remove_all_breakpoint_in_file: " + "unable to find the function requested\n"); + + return retval; +} + + +void +bp_table::remove_all_breakpoints (void) +{ + if (!instance_ok ()) + return; + + std::map< std::string, octave_user_function* >::iterator it; + for (it = instance->bp_map.begin (); it != instance->bp_map.end (); it++) + { + remove_all_breakpoints_in_file (it->first); + } +} + +std::string +do_find_bkpt_list (octave_value_list slist, + std::string match) +{ + std::string retval; + for (int i = 0; i < slist.length (); i++) + { + if (slist (i).string_value () == match) + { + retval = slist (i).string_value (); + break; + } + } + return retval; +} + + +std::map< std::string, intmap> +bp_table::get_breakpoint_list (const octave_value_list& fname_list) +{ + std::map retval; + + if (!instance_ok ()) + return retval; + + // Iterate through each of the files in the map and get the + // name and list of breakpoints + std::map< std::string, octave_user_function* >::iterator it; + for (it = instance->bp_map.begin (); it != instance->bp_map.end (); it++) + { + if (fname_list.length () == 0 || + do_find_bkpt_list (fname_list, it->first) != "") + { + octave_value_list bkpts = it->second->body ()->list_breakpoints (); + octave_idx_type len = bkpts.length (); + intmap bkpts_vec; + for (int i = 0; i < len; i++) + bkpts_vec[i] = bkpts (i).double_value (); + retval[ it->first ] = bkpts_vec; + } + } + return retval; +} + +static octave_value +intmap_to_ov (const intmap& line) +{ + int idx = 0; + NDArray retval (dim_vector (1, line.size())); + for (int i = 0; i < line.size(); i++ ) + { + intmap::const_iterator p = line.find (i); + if (p != line.end ()) + { + int lineno = p->second; + retval (idx++) = lineno; + } + } + retval.resize (dim_vector (1, idx)); + return retval; +} DEFCMD (dbstop, args, , "-*- texinfo -*-\n\ @@ -101,82 +350,15 @@ @seealso{dbclear, dbstatus, dbnext}\n\ @end deftypefn") { - octave_value retval; - int nargin = args.length (); - int idx = 0; + intmap retval; std::string symbol_name = ""; - - if (nargin != 1 && args(0).is_string()) - { - symbol_name = args(0).string_value (); - idx = 1; - } - - octave_user_function *dbg_fcn = get_user_function (symbol_name); - - if (dbg_fcn) - { - octave_idx_type nsize = 10; - RowVector results (nsize); - octave_idx_type nr = 0; - - tree_statement_list *cmds = dbg_fcn->body (); - - for (int i = idx; i < nargin; i++) - { - 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); - } + intmap lines; + parse_dbfunction_params (args, symbol_name, lines); - results(nr++) = cmds->set_breakpoint (line); - } - else - { - const NDArray arg = args(i).array_value (); - - if (error_state) - break; - - for (octave_idx_type j = 0; j < arg.nelem(); j++) - { - int line = static_cast (arg.elem (j)); - - if (error_state) - break; + if (!error_state) + retval = bp_table::add_breakpoint (symbol_name, lines); - if (nr == nsize) - { - nsize *= 2; - results.resize (nsize); - } - - results(nr++) = cmds->set_breakpoint (line); - } - - if (error_state) - break; - } - } - - if (! error_state) - { - results.resize (nr); - retval = results; - } - } - else - error ("dbstop: unable to find the function requested\n"); - - return retval; + return intmap_to_ov(retval); } DEFCMD (dbclear, args, , @@ -197,62 +379,17 @@ @end deftypefn") { octave_value retval; - int nargin = args.length (); - int idx = 0; std::string symbol_name = ""; - - if (nargin != 1 && args(0).is_string()) - { - symbol_name = args(0).string_value (); - idx = 1; - } - - octave_user_function *dbg_fcn = get_user_function (symbol_name); - - if (dbg_fcn) - { - tree_statement_list *cmds = dbg_fcn->body (); - - for (int i = idx; i < nargin; i++) - { - if (args(i).is_string ()) - { - int line = atoi (args(i).string_value ().c_str ()); - - if (error_state) - break; - - cmds->delete_breakpoint (line); - } - else - { - const NDArray arg = args(i).array_value (); - - if (error_state) - break; - - for (octave_idx_type j = 0; j < arg.nelem (); j++) - { - int line = static_cast (arg.elem (j)); - - if (error_state) - break; - - cmds->delete_breakpoint (line); - } - - if (error_state) - break; - } - } - } - else - error ("dbclear: unable to find the function requested\n"); + intmap lines; + parse_dbfunction_params (args, symbol_name, lines); + + if (!error_state) + bp_table::remove_breakpoint (symbol_name, lines); return retval; } -DEFCMD (dbstatus, args, , +DEFCMD (dbstatus, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {lst =} dbstatus ([func])\n\ Return a vector containing the lines on which a function has \n\ @@ -265,50 +402,74 @@ @seealso{dbclear, dbwhere}\n\ @end deftypefn") { - octave_value retval; - + Octave_map retval; int nargin = args.length (); + octave_value_list fcn_list; + std::map< std::string, intmap> bp_list; + std::string symbol_name = ""; if (nargin != 0 && nargin != 1) { error ("dbstatus: only zero or one arguements accepted\n"); - return retval; + return octave_value (); } - std::string symbol_name = ""; - if (nargin == 1) { if (args(0).is_string ()) - symbol_name = args(0).string_value (); + { + symbol_name = args (0).string_value (); + fcn_list (0) = symbol_name; + bp_list = bp_table::get_breakpoint_list (fcn_list); + } else - gripe_wrong_type_arg ("dbstatus", args(0)); + gripe_wrong_type_arg ("dbstatus", args (0)); + } + else + { + octave_user_function *dbg_fcn = get_user_function (); + if (dbg_fcn) + { + symbol_name = dbg_fcn->name (); + fcn_list (0) = symbol_name; + } + bp_list = bp_table::get_breakpoint_list (fcn_list); } - octave_user_function *dbg_fcn = get_user_function (symbol_name); - - if (dbg_fcn) + std::map< std::string, intmap>::iterator it; + if (nargout == 1) { - tree_statement_list *cmds = dbg_fcn->body (); - - octave_value_list lst = cmds->list_breakpoints (); - - RowVector vec (lst.length (), 0.0); - - for (int i = 0; i < lst.length (); i++) + // Fill in an array for return + int i = 0; + Cell names (dim_vector (bp_list.size (), 1)); + Cell file (dim_vector (bp_list.size (), 1)); + Cell line (dim_vector (bp_list.size (), 1)); + for (it = bp_list.begin (); it != bp_list.end (); it++) { - vec(i) = lst(i).double_value (); - - if (error_state) - panic_impossible (); + names (i) = it->first; + line (i) = intmap_to_ov(it->second); + file (i) = do_which (it->first); + i++; } - - retval = octave_value (vec); + retval.assign ("name", names); + retval.assign ("file", file); + retval.assign ("line", line); + return octave_value (retval); } else - error ("dbstatus: unable to find the function you requested\n"); - - return retval; + { + // Print out the breakpoint information + for (it = bp_list.begin(); it != bp_list.end(); it++) + { + octave_stdout << "Breakpoint in " << it->first << " at line(s) "; + for (int j = 0; j < it->second.size (); j++) + if (j < it->second.size()-1) + octave_stdout << it->second [j] << ", "; + else + octave_stdout << it->second [j] << "." << std::endl; + } + return octave_value (); + } } DEFCMD (dbwhere, , , diff -r 503001863427 -r ac7179f00422 src/help.cc --- a/src/help.cc Wed Oct 31 01:09:28 2007 +0000 +++ b/src/help.cc Wed Oct 31 01:24:12 2007 +0000 @@ -1295,7 +1295,7 @@ return retval; } -static std::string +std::string do_which (const std::string& name) { std::string retval; diff -r 503001863427 -r ac7179f00422 src/help.h --- a/src/help.h Wed Oct 31 01:09:28 2007 +0000 +++ b/src/help.h Wed Oct 31 01:24:12 2007 +0000 @@ -49,6 +49,8 @@ // (--info-program program) extern std::string Vinfo_program; +extern std::string do_which (const std::string& name); + #endif /*