Mercurial > octave
changeset 33060:50e19b01e111
make dblist and dbtype follow debugger stack frame pointer (bug #65330)
* utils.h, utils.cc (display_file_lines): New function.
* pt-eval.h, pt-eval.cc (tree_evaluator::debug_list,
tree_evaluator::debug_type): New functions.
* stack-frame.h, stack-frame.cc (stack_frame::debug_where):
New alias for display_stopped_in_message.
(stack_frame::debug_list, stack_frame::debug_list): New functions.
* debug.cc (do_dbtype): Delete static function.
(Fdbtype): Decode arguments and forward to either display_file_lines
or tree_evaluator::debug_type.
(Fdblist): Decode arguments and forward to tree_evaluator::debug_list.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Tue, 20 Feb 2024 15:04:18 -0500 |
parents | 7ca23b98c04f |
children | 3bb4422bd982 406c7ef068af |
files | libinterp/corefcn/debug.cc libinterp/corefcn/stack-frame.cc libinterp/corefcn/stack-frame.h libinterp/corefcn/utils.cc libinterp/corefcn/utils.h libinterp/parse-tree/pt-eval.cc libinterp/parse-tree/pt-eval.h |
diffstat | 7 files changed, 130 insertions(+), 122 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/debug.cc Tue Feb 20 10:45:34 2024 -0800 +++ b/libinterp/corefcn/debug.cc Tue Feb 20 15:04:18 2024 -0500 @@ -592,37 +592,6 @@ return ovl (); } -static void -do_dbtype (std::ostream& os, const std::string& name, int start, int end) -{ - std::string ff = octave::fcn_file_in_path (name); - - if (ff.empty ()) - os << "dbtype: unknown function " << name << "\n"; - else - { - std::ifstream fs = octave::sys::ifstream (ff.c_str (), std::ios::in); - - if (! fs) - os << "dbtype: unable to open '" << ff << "' for reading!\n"; - else - { - int line = 1; - std::string text; - - while (std::getline (fs, text) && line <= end) - { - if (line >= start) - os << line << "\t" << text << "\n"; - - line++; - } - } - } - - os.flush (); -} - DEFMETHOD (dbtype, interp, args, , doc: /* -*- texinfo -*- @deftypefn {} {} dbtype @@ -647,23 +616,17 @@ @seealso{dblist, dbwhere, dbstatus, dbstop} @end deftypefn */) { - octave_user_code *dbg_fcn; - string_vector argv = args.make_argv ("dbtype"); - octave::tree_evaluator& tw = interp.get_evaluator (); + // Empty means current function on call stack. + std::string fcn_name; + + int start = 0; + int end = std::numeric_limits<int>::max (); switch (args.length ()) { case 0: // dbtype - dbg_fcn = tw.get_user_code (); - - if (! dbg_fcn) - error ("dbtype: must be inside a user function to give no arguments to dbtype\n"); - - do_dbtype (octave_stdout, dbg_fcn->fcn_file_name (), - 0, std::numeric_limits<int>::max ()); - break; case 1: // (dbtype start:end) || (dbtype fcn) || (dbtype lineno) @@ -674,54 +637,34 @@ if (ind != std::string::npos) // (dbtype start:end) { - dbg_fcn = tw.get_user_code (); - - if (dbg_fcn) - { - std::string start_str = arg.substr (0, ind); - std::string end_str = arg.substr (ind + 1); + std::string start_str = arg.substr (0, ind); + std::string end_str = arg.substr (ind + 1); - int start, end; - start = atoi (start_str.c_str ()); - if (end_str == "end") - end = std::numeric_limits<int>::max (); - else - end = atoi (end_str.c_str ()); + start = atoi (start_str.c_str ()); + if (end_str == "end") + end = std::numeric_limits<int>::max (); + else + end = atoi (end_str.c_str ()); - if (std::min (start, end) <= 0) - error ("dbtype: start and end lines must be >= 1\n"); + if (std::min (start, end) <= 0) + error ("dbtype: start and end lines must be >= 1\n"); - if (start > end) - error ("dbtype: start line must be less than end line\n"); - - do_dbtype (octave_stdout, dbg_fcn->fcn_file_name (), - start, end); - } + if (start > end) + error ("dbtype: start line must be less than end line\n"); } else // (dbtype fcn) || (dbtype lineno) { int line = atoi (arg.c_str ()); if (line == 0) // (dbtype fcn) - { - dbg_fcn = tw.get_user_code (arg); - - if (! dbg_fcn) - error ("dbtype: function <%s> not found\n", arg.c_str ()); - - do_dbtype (octave_stdout, dbg_fcn->fcn_file_name (), - 0, std::numeric_limits<int>::max ()); - } + fcn_name = arg; else // (dbtype lineno) { if (line <= 0) error ("dbtype: start and end lines must be >= 1\n"); - dbg_fcn = tw.get_user_code (); - - if (dbg_fcn) - do_dbtype (octave_stdout, dbg_fcn->fcn_file_name (), - line, line); + start = line; + end = line; } } } @@ -729,13 +672,9 @@ case 2: // (dbtype fcn start:end) || (dbtype fcn start) { - dbg_fcn = tw.get_user_code (argv[1]); - - if (! dbg_fcn) - error ("dbtype: function <%s> not found\n", argv[1].c_str ()); + fcn_name = argv[1]; std::string arg = argv[2]; - int start, end; std::size_t ind = arg.find (':'); if (ind != std::string::npos) @@ -760,8 +699,6 @@ if (start > end) error ("dbtype: start line must be less than end line\n"); - - do_dbtype (octave_stdout, dbg_fcn->fcn_file_name (), start, end); } break; @@ -769,6 +706,22 @@ error ("dbtype: expecting zero, one, or two arguments\n"); } + if (fcn_name.empty ()) + { + octave::tree_evaluator& tw = interp.get_evaluator (); + + tw.debug_type (octave_stdout, start, end); + } + else + { + std::string file_name = octave::fcn_file_in_path (fcn_name); + + if (file_name.empty ()) + error ("dbtype: unknown function '%s'", fcn_name.c_str ()); + + octave::display_file_lines (octave_stdout, file_name, start, end, -1, "", "dbtype"); + } + return ovl (); } @@ -785,7 +738,12 @@ { int n = 10; - if (args.length () == 1) + int numel = args.length (); + + if (numel > 1) + print_usage (); + + if (numel == 1) { octave_value arg = args(0); @@ -804,44 +762,7 @@ octave::tree_evaluator& tw = interp.get_evaluator (); - octave_user_code *dbg_fcn = tw.get_user_code (); - - if (! dbg_fcn) - error ("dblist: must be inside a user function to use dblist\n"); - - bool have_file = true; - - std::string name = dbg_fcn->fcn_file_name (); - - if (name.empty ()) - { - have_file = false; - name = dbg_fcn->name (); - } - - int l = tw.debug_user_code_line (); - - if (l > 0) - { - if (have_file) - { - int l_min = std::max (l - n/2, 0); - int l_max = l + n/2; - do_dbtype (octave_stdout, name, l_min, l-1); - - std::string line = dbg_fcn->get_code_line (l); - - if (! line.empty ()) - octave_stdout << l << "-->\t" << line << std::endl; - - do_dbtype (octave_stdout, name, l+1, l_max); - } - } - else - { - octave_stdout << "dblist: unable to determine source code line" - << std::endl; - } + tw.debug_list (octave_stdout, n); return ovl (); }
--- a/libinterp/corefcn/stack-frame.cc Tue Feb 20 10:45:34 2024 -0800 +++ b/libinterp/corefcn/stack-frame.cc Tue Feb 20 15:04:18 2024 -0500 @@ -30,6 +30,7 @@ #include <iostream> #include "lo-regexp.h" +#include "lo-sysdep.h" #include "str-vec.h" #include "defun.h" @@ -48,6 +49,7 @@ #include "syminfo.h" #include "symrec.h" #include "symscope.h" +#include "utils.h" #include "variables.h" OCTAVE_BEGIN_NAMESPACE(octave) @@ -1483,6 +1485,24 @@ } void +stack_frame::debug_list (std::ostream& os, int num_lines) const +{ + std::string file_name = fcn_file_name (); + + int target_line = line (); + int start = std::max (target_line - num_lines/2, 0); + int end = target_line + num_lines/2; + + display_file_lines (os, fcn_file_name (), start, end, target_line, "-->", "dblist"); +} + +void +stack_frame::debug_type (std::ostream& os, int start_line, int end_line) const +{ + display_file_lines (os, fcn_file_name (), start_line, end_line, -1, "", "dbtype"); +} + +void stack_frame::display (bool follow) const { std::ostream& os = octave_stdout;
--- a/libinterp/corefcn/stack-frame.h Tue Feb 20 10:45:34 2024 -0800 +++ b/libinterp/corefcn/stack-frame.h Tue Feb 20 15:04:18 2024 -0500 @@ -561,6 +561,15 @@ void display_stopped_in_message (std::ostream& os) const; + void debug_where (std::ostream& os) const + { + display_stopped_in_message (os); + } + + void debug_list (std::ostream& os, int num_lines) const; + + void debug_type (std::ostream& os, int start_line, int end_line) const; + virtual void mark_scope (const symbol_record&, scope_flags) = 0; virtual void display (bool follow = true) const;
--- a/libinterp/corefcn/utils.cc Tue Feb 20 10:45:34 2024 -0800 +++ b/libinterp/corefcn/utils.cc Tue Feb 20 15:04:18 2024 -0500 @@ -803,6 +803,35 @@ return retval; } +void +display_file_lines (std::ostream& os, const std::string& file_name, int start, int end, int target_line, const std::string& marker, const std::string& who) +{ + std::ifstream fs = octave::sys::ifstream (file_name.c_str (), std::ios::in); + + if (! fs) + os << who << ": unable to open '" << file_name << "' for reading!\n"; + else + { + int line_num = 1; + std::string text; + + while (std::getline (fs, text) && line_num <= end) + { + if (line_num >= start) + { + os << line_num; + + if (line_num == target_line) + os << marker; + + os << "\t" << text << "\n"; + } + + line_num++; + } + } +} + // Replace backslash escapes in a string with the real values. std::string
--- a/libinterp/corefcn/utils.h Tue Feb 20 10:45:34 2024 -0800 +++ b/libinterp/corefcn/utils.h Tue Feb 20 15:04:18 2024 -0500 @@ -135,6 +135,9 @@ extern OCTINTERP_API std::string fcn_file_in_path (const std::string&); +extern OCTINTERP_API void +display_file_lines (std::ostream& os, const std::string& file_name, int start, int end, int target_line, const std::string& marker, const std::string& who); + extern OCTINTERP_API std::string do_string_escapes (const std::string& s); extern OCTINTERP_API const char * undo_string_escape (char c);
--- a/libinterp/parse-tree/pt-eval.cc Tue Feb 20 10:45:34 2024 -0800 +++ b/libinterp/parse-tree/pt-eval.cc Tue Feb 20 15:04:18 2024 -0500 @@ -2549,6 +2549,28 @@ frm->display_stopped_in_message (os); } +void +tree_evaluator::debug_list (std::ostream& os, int num_lines) const +{ + std::shared_ptr<stack_frame> frm = m_call_stack.current_user_frame (); + + if (! (frm->is_user_script_frame () || frm->is_user_fcn_frame ())) + error ("dblist: must be inside a user function or script to use dblist\n"); + + frm->debug_list (os, num_lines); +} + +void +tree_evaluator::debug_type (std::ostream& os, int start_line, int end_line) const +{ + std::shared_ptr<stack_frame> frm = m_call_stack.current_user_frame (); + + if (! (frm->is_user_script_frame () || frm->is_user_fcn_frame ())) + error ("dbtype: must be inside a user function or script to use dbtype\n"); + + frm->debug_type (os, start_line, end_line); +} + octave_user_code * tree_evaluator::current_user_code () const {
--- a/libinterp/parse-tree/pt-eval.h Tue Feb 20 10:45:34 2024 -0800 +++ b/libinterp/parse-tree/pt-eval.h Tue Feb 20 15:04:18 2024 -0500 @@ -466,6 +466,10 @@ void debug_where (std::ostream& os) const; + void debug_list (std::ostream& os, int num_lines) const; + + void debug_type (std::ostream& os, int start_line, int end_line) const; + octave_user_code * current_user_code () const; unwind_protect * curr_fcn_unwind_protect_frame ();