# HG changeset patch # User jwe # Date 983465673 0 # Node ID 44386b0e53da4931814ae9f4ebd45854afad264a # Parent 4073be5aefa1299729e7f6ee0dcf8abd633d844a [project @ 2001-03-01 16:54:31 by jwe] diff --git a/configure.in b/configure.in --- a/configure.in +++ b/configure.in @@ -21,7 +21,7 @@ ### Software Foundation, 59 Temple Place - Suite 330, Boston, MA ### 02111-1307, USA. -AC_REVISION($Revision: 1.341 $) +AC_REVISION($Revision: 1.342 $) AC_PREREQ(2.9) AC_INIT(src/octave.cc) AC_CONFIG_HEADER(config.h) @@ -853,8 +853,17 @@ AC_ISC_POSIX AC_MINIX AC_AIX -AC_CHECK_FUNC(getpwnam, , AC_CHECK_LIB(sun, getpwnam)) -AC_CHECK_FUNC(gethostname, , AC_CHECK_LIB(socket, gethostname)) +AC_CHECK_FUNCS(gethostname getpwnam) +if test "$ac_cv_func_gethostname" = yes; then + true +else + AC_CHECK_LIB(socket, gethostname) +fi +if test "$ac_cv_func_getpwnam" = yes; then + true +else + AC_CHECK_LIB(sun, getpwnam) +fi ### How big are ints and how are they oriented? These could probably ### be eliminated in favor of run-time checks. diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,56 @@ 2001-02-28 John W. Eaton + * pt.h (tree::break_statement): New static member. + (tree::break_function): Make const. + * pt.cc (tree::break_statement): Initialize here. + (tree::break_function): Make const. + * pb-bp.h (break_statement): Delete global varaible declaration. + * pt-bp.cc (break_statement): Delete global variable definition. + + * pt-bp.h (tree_breakpoint::bp_list): Rename from lst. + + * pt.h: Don't inlcude ov-usr-fcn.h. + Provide forward declaration of octave_user_function class. + +2001-02-28 Ben Sapp + + * debug.cc (get_user_function): Simplify by using curr_function. + (Fdbg_where): New function. + (Fdbg_list): Now DLD_TEXT instead of DLD_FCN. + (Fdbg_set): Likewise. + (Fdbg_delete): Likewise. + + * pt-bp.h (break_statement): New global variable. + (MAYBE_DO_BREAKPOINT): Check for dbg_next and dbg_step. + Print line, column, and current statement. + * pt-bp.cc (break_statement): New global variable + (tree_breakpoint::visit_do_until_command): Return immediately if + we've already found the line. + (tree_breakpoint::visit_colon_expression): Set breakpoint info here. + (tree_breakpoint::visit_binary_expression): Recurse here when + checking for breakpoints. + + * debug.cc: Move here from DLD-FUNCTIONS/debug.cc. + * Makefile.in (DIST_SRC): Add it to the list. + (DLD_XSRC): Delete it from the list. + + * pt.h (tree::last_line, tree::break_function): New static members. + * pt.cc(tree::last_line, tree::break_function): Initialize them. + + * pt-cell.h (tree_cell::tree_cell): Accept line and column info. + * pt-mat.h (tree_matrix::tree_matrix): Likewise. + + * ov-usr-fcn.h (octave_user_function::sym_tab): Delete. + + * input.cc (get_user_input): Handle dbg_next. + Set tree:break_function and tree::last_line when doing dbg_step. + +2001-02-28 John W. Eaton + + * lex.l (handle_string): Save line and column information in token. + (is_keyword): Save line and column information for plot style and + axes tokens. + * toplev.cc (main_loop): Set retval to non-zero value if error occurs when not interactive. diff --git a/src/DLD-FUNCTIONS/debug.cc b/src/DLD-FUNCTIONS/debug.cc deleted file mode 100644 --- a/src/DLD-FUNCTIONS/debug.cc +++ /dev/null @@ -1,331 +0,0 @@ -/* - -Copyright (C) 2001 Ben Sapp - -This file is part of Octave. - -Octave is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any -later version. - -Octave is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with Octave; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "error.h" -#include "input.h" -#include "pager.h" -#include "oct-obj.h" -#include "utils.h" -#include "parse.h" -#include "symtab.h" -#include "gripes.h" -#include "ov.h" -#include "ov-usr-fcn.h" -#include "ov-fcn.h" -#include "pt-pr-code.h" -#include "pt-stmt.h" -#include "toplev.h" -#include "unwind-prot.h" -#include "variables.h" -#include "defun-dld.h" -#include "defun-int.h" - -octave_user_function * -get_user_function (std::string str = "") -{ - octave_user_function *dbg_fcn = NULL; - - if (curr_sym_tab != top_level_sym_tab) - { - Array srs = - top_level_sym_tab->symbol_list ("*", - symbol_record::USER_FUNCTION, - SYMTAB_ALL_SCOPES); - int len = srs.length (); - - for (int i = 0; i < len ; i++) - { - symbol_record *ptr = srs(i); - - if (ptr && ptr->is_user_function ()) - { - octave_value tmp = ptr->def (); - octave_user_function *tmp_fcn - = static_cast (tmp.function_value ()); - symbol_table *st = tmp_fcn->sym_table (); - - if (st == curr_sym_tab) - { - dbg_fcn = tmp_fcn; - break; - } - } - } - - } - else if (str.compare ("")) - { - symbol_record *ptr = curr_sym_tab->lookup (str); - - if (ptr && ptr->is_user_function ()) - { - octave_value tmp = ptr->def (); - dbg_fcn = static_cast (tmp.function_value ()); - } - else - { - symbol_record *ptr = lookup_by_name (str, false); - - if (ptr && ptr->is_user_function ()) - { - octave_value tmp = ptr->def (); - dbg_fcn = static_cast (tmp.function_value ()); - } - } - } - - return dbg_fcn; -} - -DEFUN_DLD (dbg_set, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {rline =} dbg_set (func, line)\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\ -@end table\n\ -\n\ -The rline returned is the real line that the breakpoint was set at.\n\ -\n\ -@end deftypefn\n\ -@seealso{dbg_delete, dbg_list, dbg_cont}") -{ - octave_value_list retval; - int result = -1; - int nargin = args.length (); - - if (nargin == 2) - { - if (!args(0).is_string ()) - { - gripe_wrong_type_arg ("dbg_set", args(0)); - return retval; - } - - std::string symbol_name = args(0).string_value (); - - if (!args(1).is_real_scalar ()) - { - gripe_wrong_type_arg ("dbg_set", args(1)); - return retval; - } - - int line = int(args(1).double_value ()); - octave_user_function *dbg_fcn = get_user_function (symbol_name); - - if (dbg_fcn) - { - tree_statement_list *cmds = dbg_fcn->body (); - result = cmds->set_breakpoint (line); - } - else - error ("unable to find the function requested\n"); - } - else if (nargin == 1) - { - if (!args(0).is_real_scalar ()) - { - gripe_wrong_type_arg ("dbg_set", args(1)); - return retval; - } - - int line = int(args(0).double_value ()); - octave_user_function *dbg_fcn = get_user_function (); - - if (dbg_fcn) - { - tree_statement_list *cmds = dbg_fcn->body (); - result = cmds->set_breakpoint (line); - } - else - error ("unable to find the function requested\n"); - } - else - error ("one argument when in a function and two when not.\n"); - - retval = double(result); - return retval; -} - -DEFUN_DLD (dbg_delete, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} dbg_delete (func, line)\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\ -@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\ -@end deftypefn\n\ -@seealso{dbg_delete, dbg_list, dbg_cont}") -{ - octave_value_list retval; - int line = -1; - std::string symbol_name = ""; - int nargin = args.length (); - - if ((nargin != 1) && (nargin != 2)) - { - error ("need one or two arguements\n"); - return retval; - } - - if (nargin == 2) - { - if (!args(0).is_string ()) - { - gripe_wrong_type_arg ("dbg_delete", args(0)); - return retval; - } - - std::string symbol_name = args(0).string_value (); - - if (!args(1).is_real_scalar ()) - { - gripe_wrong_type_arg ("dbg_delete", args(1)); - return retval; - } - - line = int(args(1).double_value ()); - } - else if (nargin == 1) - { - if (!args(1).is_real_scalar ()) - { - gripe_wrong_type_arg ("dbg_delete", args(1)); - return retval; - } - - line = int(args(1).double_value ()); - } - else - { - error ("need one or two arguements\n"); - return retval; - } - - 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 ("unable to find the function requested\n"); - return retval; -} - -DEFUN_DLD (dbg_list, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {lst =} dbg_list ([func])\n\ -Return a vector containing the lines on which a function has \n\ -breakpoints set.\n\ -@table @code\n\ -@item func\n\ -String representing the function name. When already in debug\n\ -mode this should be left out.\n\ -@end table\n\ -@end deftypefn\n\ -@seealso{dbg_delete, dbg_set, dbg_cont}") -{ - octave_value_list retval; - octave_value_list lst; - RowVector vec; - int nargin = args.length (); - - if ((nargin != 0) && (nargin != 1)) - { - error ("only zero or one arguements accepted\n"); - return retval; - } - - std::string symbol_name = ""; - - if (nargin == 1) - { - if (args(0).is_string ()) - symbol_name = args(0).string_value (); - else - gripe_wrong_type_arg ("dbg_list", args(0)); - } - - octave_user_function *dbg_fcn = get_user_function (symbol_name); - - if (dbg_fcn) - { - tree_statement_list *cmds = dbg_fcn->body (); - lst = cmds->list_breakpoints (); - vec = RowVector (lst.length (), 0.0); - - for (int i = 0; i < lst.length (); i++) - { - if(lst(i).is_real_scalar ()) - { - double x = lst(i).double_value (); - - if (! error_state) - vec(i) = x; - else - panic_impossible (); - } - else - panic_impossible (); - } - } - else - error ("unable to find the function you requested"); - - return octave_value(vec); -} - - -DEFUN_DLD (dbg_where, , , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} dbg_where ()\n\ -Show where we are in the code\n\ -@end deftypefn\n") -{ - octave_value retval; - - warning ("not implemented"); - - return retval; -} - -/* -;;; Local Variables: *** -;;; mode: C++ *** -;;; End: *** -*/ diff --git a/src/Makefile.in b/src/Makefile.in --- a/src/Makefile.in +++ b/src/Makefile.in @@ -40,7 +40,7 @@ endif DLD_XSRC := balance.cc besselj.cc betainc.cc chol.cc colloc.cc dassl.cc \ - debug.cc det.cc eig.cc expm.cc fft.cc fft2.cc filter.cc find.cc \ + det.cc eig.cc expm.cc fft.cc fft2.cc filter.cc find.cc \ fsolve.cc gammainc.cc getgrent.cc getpwent.cc getrusage.cc \ givens.cc hess.cc ifft.cc ifft2.cc inv.cc log.cc lpsolve.cc \ lsode.cc lu.cc minmax.cc pinv.cc qr.cc quad.cc qz.cc rand.cc \ @@ -122,7 +122,7 @@ DIST_SRC := BaseSLList.cc Cell.cc DLList.cc Map.cc SLList.cc \ SLStack.cc Stack.cc c-file-ptr-stream.cc comment-list.cc \ - cutils.c data.cc \ + cutils.c data.cc debug.cc \ defaults.cc defun.cc dirfns.cc dynamic-ld.cc error.cc \ file-io.cc fn-cache.cc gripes.cc help.cc input.cc lex.l \ load-save.cc mappers.cc matherr.c oct-fstrm.cc oct-hist.cc \ diff --git a/src/debug.cc b/src/debug.cc new file mode 100644 --- /dev/null +++ b/src/debug.cc @@ -0,0 +1,317 @@ +/* + +Copyright (C) 2001 Ben Sapp + +This file is part of Octave. + +Octave is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +Octave is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with Octave; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "defun.h" +#include "error.h" +#include "input.h" +#include "pager.h" +#include "oct-obj.h" +#include "utils.h" +#include "parse.h" +#include "symtab.h" +#include "gripes.h" +#include "ov.h" +#include "ov-usr-fcn.h" +#include "ov-fcn.h" +#include "pt-pr-code.h" +#include "pt.h" +#include "pt-bp.h" +#include "pt-stmt.h" +#include "toplev.h" +#include "unwind-prot.h" +#include "variables.h" + +octave_user_function * +get_user_function (std::string str = "") +{ + octave_user_function *dbg_fcn = NULL; + + if (curr_function) + { + dbg_fcn = curr_function; + } + else if (str.compare ("")) + { + symbol_record *ptr = curr_sym_tab->lookup (str); + + if (ptr && ptr->is_user_function ()) + { + octave_value tmp = ptr->def (); + dbg_fcn = static_cast (tmp.function_value ()); + } + else + { + symbol_record *ptr = lookup_by_name (str, false); + + if (ptr && ptr->is_user_function ()) + { + octave_value tmp = ptr->def (); + dbg_fcn = static_cast (tmp.function_value ()); + } + } + } + + return dbg_fcn; +} + +DEFUN_TEXT (dbg_set, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {rline =} dbg_set (func, line)\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\ +@end table\n\ +\n\ +The rline returned is the real line that the breakpoint was set at.\n\ +\n\ +@end deftypefn\n\ +@seealso{dbg_delete, dbg_list, dbg_where}") +{ + octave_value retval; + + int result = -1; + int nargin = args.length (); + + string_vector argv = args.make_argv ("dbg_set"); + + if (error_state) + return retval; + + if (nargin == 2) + { + std::string symbol_name = argv[1]; + + std::string line_number = argv[2]; + + int line = atoi (line_number.c_str ()); + + octave_user_function *dbg_fcn = get_user_function (symbol_name); + + if (dbg_fcn) + { + tree_statement_list *cmds = dbg_fcn->body (); + result = cmds->set_breakpoint (line); + } + else + error ("unable to find the function requested\n"); + } + else if (nargin == 1) + { + std::string line_number = argv[1]; + + int line = atoi (line_number.c_str ()); + + octave_user_function *dbg_fcn = get_user_function (); + + if (dbg_fcn) + { + tree_statement_list *cmds = dbg_fcn->body (); + result = cmds->set_breakpoint (line); + } + else + error ("unable to find the function requested\n"); + } + else + error ("one argument when in a function and two when not\n"); + + retval = static_cast (result); + + return retval; +} + +DEFUN_TEXT (dbg_delete, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} dbg_delete (func, line)\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\ +@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\ +@end deftypefn\n\ +@seealso{dbg_set, dbg_list, dbg_where}") +{ + octave_value retval; + + std::string symbol_name = ""; + + int line = -1; + int nargin = args.length (); + + if (nargin != 1 && nargin != 2) + { + error ("need one or two arguements\n"); + return retval; + } + + string_vector argv = args.make_argv ("dbg_delete"); + + if (error_state) + return retval; + + if (nargin == 2) + { + octave_stdout << "2 input arguments\n"; + symbol_name = argv[1]; + + octave_stdout << argv[1] << std::endl; + std::string line_number = argv[2]; + + line = atoi (line_number.c_str ()); + } + else if (nargin == 1) + { + octave_stdout << "1 input argument\n"; + std::string line_number = argv[1]; + + line = atoi (line_number.c_str ()); + } + else + { + error ("need one or two arguements\n"); + return retval; + } + + 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 ("unable to find the function requested\n"); + + return retval; +} + +DEFUN_TEXT (dbg_list, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {lst =} dbg_list ([func])\n\ +Return a vector containing the lines on which a function has \n\ +breakpoints set.\n\ +@table @code\n\ +@item func\n\ +String representing the function name. When already in debug\n\ +mode this should be left out.\n\ +@end table\n\ +@end deftypefn\n\ +@seealso{dbg_delete, dbg_set, dbg_where}") +{ + octave_value retval; + + int nargin = args.length (); + + if (nargin != 0 && nargin != 1) + { + error ("only zero or one arguements accepted\n"); + return retval; + } + + std::string symbol_name = ""; + + if (nargin == 1) + { + if (args(0).is_string ()) + symbol_name = args(0).string_value (); + else + gripe_wrong_type_arg ("dbg_list", args(0)); + } + + octave_user_function *dbg_fcn = get_user_function (symbol_name); + + if (dbg_fcn) + { + 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++) + { + vec(i) = lst(i).double_value (); + + if (error_state) + panic_impossible (); + } + + retval = octave_value (vec); + } + else + error ("unable to find the function you requested\n"); + + return retval; +} + + +DEFUN_TEXT (dbg_where, , , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} dbg_where ()\n\ +Show where we are in the code\n\ +@end deftypefn\n\ +@seealso{dbg_delete, dbg_list, dbg_set}") +{ + octave_value retval; + + octave_user_function *dbg_fcn = curr_function; + + if (dbg_fcn) + { + std::string name = dbg_fcn->function_name (); + + octave_stdout << name << ":"; + + const tree *dbg_stmt = tree::break_statement; + + if (dbg_stmt) + { + octave_stdout << "line " << dbg_stmt->line () << ", "; + octave_stdout << "column " << dbg_stmt->column () << std::endl; + } + else + octave_stdout << "-1\n"; + } + else + error ("must be inside of a user function to use dbg_where\n"); + + return retval; +} + +/* +;;; Local Variables: *** +;;; mode: C++ *** +;;; End: *** +*/ diff --git a/src/input.cc b/src/input.cc --- a/src/input.cc +++ b/src/input.cc @@ -60,6 +60,7 @@ #include "pathlen.h" #include "pt.h" #include "pt-const.h" +#include "pt-stmt.h" #include "sighandlers.h" #include "symtab.h" #include "sysdep.h" @@ -553,6 +554,21 @@ else if (match_sans_spaces ("dbg_step", input_buf)) { tree::break_next = true; + + tree::last_line = 0; + + tree::break_function = curr_function; + + return retval; + } + else if (match_sans_spaces ("dbg_next", input_buf)) + { + tree::break_next = true; + + tree::last_line = curr_statement->line (); + + tree::break_function = curr_function; + return retval; } } diff --git a/src/lex.l b/src/lex.l --- a/src/lex.l +++ b/src/lex.l @@ -990,6 +990,9 @@ static int is_keyword (const std::string& s) { + int l = input_line_number; + int c = current_input_column; + if (lexer_flags.plotting) { if (lexer_flags.in_plot_style) @@ -999,7 +1002,7 @@ if (! sty.empty ()) { lexer_flags.in_plot_style = false; - yylval.tok_val = new token (sty); + yylval.tok_val = new token (sty, l, c); token_stack.push (yylval.tok_val); return STYLE; } @@ -1011,16 +1014,13 @@ if (! axes.empty ()) { lexer_flags.in_plot_axes = false; - yylval.tok_val = new token (axes); + yylval.tok_val = new token (axes, l, c); token_stack.push (yylval.tok_val); return AXES_TAG; } } } - int l = input_line_number; - int c = current_input_column; - int len = s.length (); const octave_kw *kw = octave_kw_lookup (s.c_str (), len); @@ -1885,6 +1885,9 @@ { std::ostrstream buf; + int bos_line = input_line_number; + int bos_col = current_input_column; + int c; int escape_pending = 0; @@ -1949,7 +1952,7 @@ lexer_flags.convert_spaces_to_comma = true; } - yylval.tok_val = new token (s); + yylval.tok_val = new token (s, bos_line, bos_col); token_stack.push (yylval.tok_val); if (delim == '\'') diff --git a/src/ov-usr-fcn.h b/src/ov-usr-fcn.h --- a/src/ov-usr-fcn.h +++ b/src/ov-usr-fcn.h @@ -133,8 +133,6 @@ octave_comment_list *trailing_comment (void) { return trail_comm; } - symbol_table *sym_table (void) { return sym_tab; } - void accept (tree_walker& tw); private: diff --git a/src/pt-bp.cc b/src/pt-bp.cc --- a/src/pt-bp.cc +++ b/src/pt-bp.cc @@ -51,7 +51,7 @@ { if (tr.is_breakpoint ()) { - lst.append (octave_value (static_cast (tr.line ()))); + bp_list.append (octave_value (static_cast (tr.line ()))); line = tr.line () + 1; } } @@ -84,11 +84,14 @@ void tree_breakpoint::visit_do_until_command (tree_do_until_command& cmd) { - tree_statement_list *lst = cmd.body (); + if (found) + return; if (cmd.line () >= line) take_action (cmd); + tree_statement_list *lst = cmd.body (); + if (lst) lst->accept (*this); @@ -126,13 +129,10 @@ tree_expression *rhs = expr.rhs (); if (lhs && lhs->line () >= line) - { - take_action (expr); - return; - } + lhs->accept (*this); if (rhs && rhs->line () >= line) - take_action (expr); + rhs->accept (*this); } void @@ -151,6 +151,9 @@ if (found) return; + if (expr.line () >= line) + take_action (expr); + tree_expression *base = expr.base (); if (base) diff --git a/src/pt-bp.h b/src/pt-bp.h --- a/src/pt-bp.h +++ b/src/pt-bp.h @@ -28,7 +28,10 @@ #endif #include "input.h" +#include "ov-usr-fcn.h" #include "pt-walk.h" +#include "pt-pr-code.h" +#include "toplev.h" class tree; @@ -40,7 +43,7 @@ enum action { set = 1, clear = 2, list = 3 }; tree_breakpoint (int l, action a) - : line (l), act (a), found (false), lst () { } + : line (l), act (a), found (false), bp_list () { } ~tree_breakpoint (void) { } @@ -140,7 +143,7 @@ void visit_unwind_protect_command (tree_unwind_protect_command&); - octave_value_list get_list (void) { return lst; } + octave_value_list get_list (void) { return bp_list; } int get_line (void) { return line; } @@ -148,13 +151,17 @@ void take_action (tree &tr); + // Statement line number we are looking for. int line; + // What to do. action act; - + + // Have we already found the line? bool found; - octave_value_list lst; + // List of breakpoint line numbers. + octave_value_list bp_list; // No copying! @@ -166,10 +173,28 @@ #define MAYBE_DO_BREAKPOINT \ do \ { \ - if (tree::break_next || is_breakpoint ()) \ + if ((tree::break_next && tree::last_line == 0) \ + || (tree::break_next \ + && curr_function == tree::break_function \ + && tree::last_line != line ()) \ + || is_breakpoint ()) \ { \ tree::break_next = false; \ - octave_stdout << "line: " << line () << std::endl; \ + \ + if (curr_function) \ + octave_stdout << curr_function->function_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 (); \ } \ } \ diff --git a/src/pt-cell.h b/src/pt-cell.h --- a/src/pt-cell.h +++ b/src/pt-cell.h @@ -46,7 +46,7 @@ { public: - tree_cell (tree_argument_list *row = 0) : tree_matrix (row) { } + tree_cell (tree_argument_list *row = 0, int line = -1, int column = -1) : tree_matrix (row, line, column) { } ~tree_cell (void) { } diff --git a/src/pt-mat.h b/src/pt-mat.h --- a/src/pt-mat.h +++ b/src/pt-mat.h @@ -47,8 +47,8 @@ { public: - tree_matrix (tree_argument_list *row = 0) - : tree_expression (), SLList () + tree_matrix (tree_argument_list *row = 0, int line = -1, int column = -1) + : tree_expression (line, column), SLList () { if (row) append (row); diff --git a/src/pt.cc b/src/pt.cc --- a/src/pt.cc +++ b/src/pt.cc @@ -38,6 +38,15 @@ // If true, stop executing at the next possible point. bool tree::break_next = false; +// The line where dbg_next was executed. +int tree::last_line = 0; + +// The function where the last breakpoint occurred. +const octave_user_function *tree::break_function = 0; + +// The statement where the last breakpoint occurred. +const tree *break_statement = 0; + // Hide the details of the string buffer so that we are less likely to // create a memory leak. diff --git a/src/pt.h b/src/pt.h --- a/src/pt.h +++ b/src/pt.h @@ -31,6 +31,7 @@ #include +class octave_user_function; class tree_walker; // Base class for the parse tree. @@ -69,6 +70,15 @@ // If true, stop executing at the next possible point. static bool break_next; + + // The line where dbg_next was executed. + static int last_line; + + // The function where the last breakpoint occurred. + static const octave_user_function *break_function; + + // The statement where the last breakpoint occurred. + static const tree *break_statement; private: