octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Changeset] Re: Q: Low hanging fruit?


From: David Bateman
Subject: Re: [Changeset] Re: Q: Low hanging fruit?
Date: Tue, 13 May 2008 21:23:30 +0200
User-agent: Thunderbird 2.0.0.12 (X11/20080306)

David Bateman wrote:
> John W. Eaton wrote:
>> Instead of adding ad-hoc parsing to the get_user_input function, I
>> think it would be better to make dbstep a normal function that
>> examines its arguments and sets some global variables that are used by
>> the get_user_input function.  Is that possible?  
> Maybe, I can try it that way instead..
>> It might also be
>> worth trying to use the normal parse/eval loop instead of eval_string
>> so that we can accept multiple line input in debug mode.
>>   
> This would be great as one of the nice features of the matlab debugger
> is that when you go into the debug mode you can cut and paste directly
> to piece of suspect code at the debug prompt and test it, whereas with
> Octave you have to convert it to a single line before pasting it.
> However, I'm not sure I see how that should be done. Do we stay in
> get_user_input as at present and call the parser from there, or are we
> in the main parser loop with the some flag set that causes us to
> fallback into get_user_input from the MAYBE_DO_BREAKPOINT macro? I'd
> rather not implement this at this point personally.
> 
> D.
> 
> 

Ok then what about the attached instead. It moves

* dbcont, dbnext, dbstep functions to DEFCMD's
* adds the dbquit function
* modifies the dbstep command to be compatible
* splits get_user_input into two versions, with the debug version using
the standard parser and thus allowing multi-line input and things like
"x = 1; return" in the debug mode to work.
* Makes the quit, exit commands at the debug prompt quit Octave in the
same manner as in Matlab.
* Updates the debug.txi file.

Making the debug mode accept multi-line input was much easier than I
thought it would be. I've tested this a little, but a little more
testing might be a good thing.

Cheers
David

# HG changeset patch
# User David Bateman <address@hidden>
# Date 1210705932 -7200
# Node ID 7349072aa6a27549880871e9a9aca939f9fc956e
# Parent  e4affe5a2f978db78f6efbd705a79304b3bdc3d9
Add dbquit and make dbstep compatible. Use parser in debug mode to handle 
multi-line input

diff --git a/ChangeLog b/ChangeLog
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@ 2008-04-27  David Bateman  <address@hidden
+2008-05-13  David Bateman  <address@hidden>
+
+       * PROJECTS: Remove implemented debugging features.
+
 2008-04-27  David Bateman  <address@hidden>
 
        * configure.in (AC_CHECK_FUNCS): Add expm1, lgammaf, lgammaf_r,
diff --git a/PROJECTS b/PROJECTS
--- a/PROJECTS
+++ b/PROJECTS
@@ -175,15 +175,6 @@ Interpreter:
 -----------
 
   * Allow customization of the debug prompt.
-
-  * For the keyboard function, parse return (or quit) more
-    intelligently so that something like
-
-      debug> x = 1; return
-
-    will work as expected.
-
-  * Handle multi-line input at the keyboard/debug prompt correctly.
 
   * Fix the parser so that
 
diff --git a/doc/ChangeLog b/doc/ChangeLog
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -1,3 +1,10 @@ 2008-05-03  Rafael Laboissiere <address@hidden
+2008-05-13  David Bateman  <address@hidden>
+
+       * interpreter/debug.txi: Uodate documentation for multiline
+       input. Add documentation for dbcont, dbquit, dbstep, dbstqck, dbup
+       and dbdown functions.
+       * interpreter/octave.texi: Upodate index for debugging functions.
+
 2008-05-03  Rafael Laboissiere <address@hidden>
 
        * interpreter/expr.txi, interpreter/tips.txi: Use ischar instead of
diff --git a/doc/interpreter/debug.txi b/doc/interpreter/debug.txi
--- a/doc/interpreter/debug.txi
+++ b/doc/interpreter/debug.txi
@@ -27,25 +27,14 @@ errors.
 errors.
 
 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
-
address@hidden
-debug> for i = 1:n, foo(i); endfor
address@hidden example
-
address@hidden
-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}, @code{exit}, @code{return} or @code{dbcont}.
+debug mode.
 
 @menu
 * Entering Debug Mode::
+* Leaving Debug Mode::
 * Breakpoints::
 * Debug Mode::
+* Call Stack::
 @end menu
 
 @node Entering Debug Mode
@@ -64,6 +53,22 @@ the functions @code{debug_on_interrupt},
 @DOCSTRING(debug_on_warning)
 
 @DOCSTRING(debug_on_error)
+
address@hidden Leaving Debug Mode
address@hidden Leavinging Debug Mode
+
+To leave the debug mode, you should simply type either @code{dbcont} 
+or @code{return}.
+
address@hidden(dbcont}
+
+To quit debug mode and return directly to the prompt @code{dbquit}
+should be used instead
+
address@hidden(dbquit)
+
+Finally, typing @code{exit} or @code{quit} at the debug prompt will
+result in Octave terminating normally.
 
 @node Breakpoints
 @section Breakpoints
@@ -132,8 +137,17 @@ Octave entered debug mode.
 @DOCSTRING(dbtype)
 
 Debug mode equally allows single line stepping through a function using
-the commands @code{dbstep} and @code{dbnext}.  These differ slightly in
-the way they treat the next executable line if the next line itself is a
-function defined in an m-file.  The @code{dbnext} command will execute
-the next line, while staying in the existing function being debugged.
-The @code{dbstep} command will step in to the new function.
+the commands @code{dbstep}.
+
address@hidden leave dbnext undocumented
+
address@hidden(dbstep)
+
address@hidden Call Stack
address@hidden Call Stack
+
address@hidden(dbstack)
+
address@hidden(dbup)
+
address@hidden(dbdown)
diff --git a/doc/interpreter/octave.texi b/doc/interpreter/octave.texi
--- a/doc/interpreter/octave.texi
+++ b/doc/interpreter/octave.texi
@@ -353,8 +353,10 @@ Debugging
 Debugging
 
 * Entering Debug Mode::
+* Leaving Debug Mode::
 * Breakpoints::
 * Debug Mode::
+* Call Stack::
 
 Input and Output
 
diff --git a/src/ChangeLog b/src/ChangeLog
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,46 @@ 2008-05-12  David Bateman  <address@hidden
+2008-05-13  David Bateman  <address@hidden>
+
+       * debug.cc (Fdbstop): If no line specified assume line 1.
+       (Fdbstep, Fdbcont, Fdbnext): Move debugging functions 
+       to normal commands.
+       (Fdbquit): New command to quit debugging mode and return to the 
+       prompt.
+       (Fdbstep): Modify the dbstep command for compatibility.
+       * input.cc (Vdebugging_current_line): Store current line being
+       debugged for use in DEFCMD versions of debug commands.
+       (match_sans_spaces_semi): Delete.
+       (static void get_debug_input (const std;string&)): New function to
+       parse input in debug mode using standard Octave parser.
+       (static octave_value_list get_user_input (const
+       octave_value_list&, int)): Remove debugging specialization.
+       * input.h (Vdebugging_current_line): Store current line being
+       debugged for use in DEFCMD versions of debug commands.
+       * parse.y (make_return_command): Special handling in debug mode.
+       * pt-bp.h (MAYBE_DO_BREAKPOINT): Support break in n lines needed
+       to support "dbstep N". 
+       * pt.cc (tree::break_next): Convert to a down counter to support
+       break in N lines. Breakpoint occure when tree::break_next is zero.
+       * toplev.cc (octave_user_script *
+       octave_call_stack::do_caller_user_script (difference_type) const):
+       Support skipping the first N functions to support "dbstep out".
+       (octave_user_function * octave_call_stack::do_caller_user_function
+       (difference_type) const): Ditto.
+       (octave_user_code * octave_call_stack::do_caller_user_code
+       (difference_type) const): Ditto.
+       * toplev.h (octave_user_script *
+       octave_call_stack::do_caller_user_script (difference_type) const):
+       Add difference_type argument.
+       (octave_user_function * octave_call_stack::do_caller_user_function
+       (difference_type) const): Ditto.
+       (octave_user_code * octave_call_stack::do_caller_user_code
+       (difference_type) const): Ditto.
+       (static octave_user_script *caller_script (difference_type)):
+       Ditto.
+       (static octave_user_function *caller_user_function
+       (difference_type q)): Ditto.
+       (static octave_user_code *caller_user_code (difference_type q)):
+       Ditto.
+
 2008-05-12  David Bateman  <address@hidden>
 
        * DLD-FUNCTIONS/sqrt.m: Replace DBL_* with FLT_* for single
diff --git a/src/debug.cc b/src/debug.cc
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -380,6 +380,9 @@ The rline returned is the real line that
 
   parse_dbfunction_params ("dbstop", args, symbol_name, lines);
 
+  if (lines.size () == 0)
+    lines[0] = 1;
+
   if (! error_state)
     retval = bp_table::add_breakpoint (symbol_name, lines);
 
@@ -833,6 +836,155 @@ If @var{n} is omitted, move down one fra
   return retval;
 }
 
+DEFCMD (dbstep, args, ,
+  "-*- texinfo -*-\n\
address@hidden {Command} {} dbstep @var{n}\n\
address@hidden {Command} {} dbstep in\n\
address@hidden {Command} {} dbstep out\n\
+In debugging mode, execute the next @var{n} lines of code. If @var{n} is\n\
+omitted execute the next line of code. If the next line of code is itself\n\
+defined in terms of an m-file remain in the existing function.\n\
+\n\
+Using @code{dbstep in} will cause execution of the next line to step into\n\
+any m-files defined on the next line. Using @code{dbstep out} with cause\n\
+execution to continue until the current function returns.\n\
address@hidden, dbquit}\n\
address@hidden deftypefn")
+{
+  if (Vdebugging)
+    {
+      int nargin = args.length ();
+      
+      if (nargin > 1)
+       print_usage ();
+      else if (nargin == 1 && args(0).is_string ())
+       {
+         std::string arg = args(0).string_value ();
+
+         if (! error_state)
+           {
+             if (arg == "in")
+               {
+                 Vdebugging = false;
+
+                 tree::break_next = 0;
+
+                 tree::last_line = 0;
+
+                 tree::break_function = octave_call_stack::caller_user_code ();
+               }
+             else if (arg == "out")
+               {
+                 Vdebugging = false;
+
+                 tree::break_next = 0;
+
+                 tree::last_line = -1;
+
+                 // Next to skip 2 here. One for the oct-file dbstep and 
+                 // another for the function we actually want to step out of.
+                 tree::break_function = octave_call_stack::caller_user_code 
(2);
+               }
+             else
+               {
+                 int n = atoi (arg.c_str ());
+
+                 Vdebugging = false;
+
+                 if (n < 0)
+                   tree::break_next = 0;
+                 else
+                   tree::break_next = n;
+
+                 tree::last_line = Vdebugging_current_line;
+                 
+                 tree::break_function = octave_call_stack::caller_user_code ();
+               }
+           }
+       }
+      else
+       {
+         Vdebugging = false;
+
+         tree::break_next = 0;
+
+         tree::last_line = Vdebugging_current_line;
+                 
+         tree::break_function = octave_call_stack::caller_user_code ();
+       }
+    }
+  else
+    error ("dbstep: can only be called in debug mode");
+
+  return octave_value_list ();
+}
+
+DEFCMD (dbcont, args, ,
+  "-*- texinfo -*-\n\
address@hidden {Command} {} dbcont ()\n\
+In debugging mode, quit debugging mode and continue execution.\n\
address@hidden, dbstep}\n\
address@hidden deftypefn")
+{
+  if (Vdebugging)
+    if (args.length() == 0)
+      Vdebugging = false;
+    else
+      print_usage ();
+  else
+    error ("dbcont: can only be called in debug mode");
+
+  return octave_value_list ();
+}
+
+DEFCMD (dbquit, args, ,
+  "-*- texinfo -*-\n\
address@hidden {Command} {} dbquit ()\n\
+In debugging mode, quit debugging mode and return to the top level.\n\
address@hidden, dbcont}\n\
address@hidden deftypefn")
+{
+  if (Vdebugging)
+    if (args.length() == 0)
+      octave_throw_interrupt_exception ();
+    else
+      print_usage ();
+  else
+    error ("dbquit: can only be called in debug mode");
+
+  return octave_value_list ();
+}
+
+DEFCMD (dbnext, args, ,
+  "-*- texinfo -*-\n\
address@hidden {Command} {} dbquit ()\n\
+In debugging mode, execute the next line of code without stepping in to\n\
+functions. This is synonymous with @code{dbstep}.\n\
address@hidden, dbcont, dbquit}\n\
address@hidden deftypefn")
+{
+  if (Vdebugging)
+    {
+    if (args.length() == 0)
+      {
+       Vdebugging = false;
+
+       tree::break_next = 0;
+
+       tree::last_line = Vdebugging_current_line;
+                 
+       tree::break_function = octave_call_stack::caller_user_code ();
+      }
+    else
+      print_usage ();
+    }
+  else
+    error ("dbnext: can only be called in debug mode");
+
+  return octave_value_list ();
+}
+
+
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
diff --git a/src/input.cc b/src/input.cc
--- a/src/input.cc
+++ b/src/input.cc
@@ -147,6 +147,9 @@ bool Vdrawnow_requested = false;
 // TRUE if we are in debugging mode.
 bool Vdebugging = false;
 
+// The current line that we are debugging
+int Vdebugging_current_line = -1;
+
 // TRUE if we are running in the Emacs GUD mode.
 static bool Vgud_mode = false;
 
@@ -566,21 +569,78 @@ initialize_command_input (void)
   command_editor::set_quoting_function (quoting_filename);
 }
 
-static bool
-match_sans_spaces_semi (const std::string& standard, const std::string& test)
-{
-  size_t beg = test.find_first_not_of (" \t");
-
-  if (beg != NPOS)
-    {
-      size_t end = test.find_last_not_of ("; \t");
-
-      size_t len = end == NPOS ? NPOS : end - beg + 1;
-
-      return (test.substr (beg, len) == standard);
-    }
-
-  return false;
+static void
+get_debug_input (const std::string& prompt)
+{
+  octave_user_code *caller = octave_call_stack::caller_user_code ();
+  std::string nm;
+
+  if (caller)
+    {
+      nm = caller->fcn_file_name ();
+
+      if (nm.empty ())
+       nm = caller->name ();
+
+      Vdebugging_current_line = octave_call_stack::current_line ();
+    }
+  else
+    Vdebugging_current_line = -1;
+
+  std::ostringstream buf;
+
+  if (! nm.empty ())
+    {
+      if (Vgud_mode)
+       {
+         static char ctrl_z = 'Z' & 0x1f;
+
+         buf << ctrl_z << ctrl_z << nm << ":" << Vdebugging_current_line;
+       }
+      else
+       {
+         buf << "stopped in " << nm;
+
+         if (Vdebugging_current_line > 0)
+           buf << " at line " << Vdebugging_current_line;
+       }
+    }
+
+  std::string msg = buf.str ();
+
+  if (! msg.empty ())
+    message (Vgud_mode ? 0 : "keyboard", msg.c_str ());
+
+  unwind_protect::begin_frame ("get_debug_input");
+
+  unwind_protect_str (VPS1);
+  VPS1 = prompt;
+
+  while (Vdebugging)
+    {
+      reset_error_handler ();
+
+      reset_parser ();
+
+      // This is the same as yyparse in parse.y.
+      int retval = octave_parse ();
+
+      if (retval == 0 && global_command)
+       {
+         global_command->eval ();
+
+         delete global_command;
+
+         global_command = 0;
+
+         OCTAVE_QUIT;
+
+         if (octave_completion_matches_called)
+           octave_completion_matches_called = false;       
+       }
+    }
+
+  unwind_protect::run_frame ("get_debug_input");
 }
 
 // If the user simply hits return, this will produce an empty matrix.
@@ -597,62 +657,13 @@ get_user_input (const octave_value_list&
   if (nargin == 2)
     read_as_string++;
 
-  std::string nm;
-  int line = -1;
-
-  if (Vdebugging)
-    {
-      octave_user_code *caller = octave_call_stack::caller_user_code ();
-
-      if (caller)
-       {
-         nm = caller->fcn_file_name ();
-
-         if (nm.empty ())
-           nm = caller->name ();
-
-         line = octave_call_stack::current_line ();
-       }
-    }
-
-  std::ostringstream buf;
-
-  if (! nm.empty ())
-    {
-      if (Vgud_mode)
-       {
-         static char ctrl_z = 'Z' & 0x1f;
-
-         buf << ctrl_z << ctrl_z << nm << ":" << line;
-       }
-      else
-       {
-         buf << "stopped in " << nm;
-
-         if (line > 0)
-           buf << " at line " << line;
-       }
-    }
-
-  std::string msg = buf.str ();
-
-  if (! msg.empty ())
-    message (Vgud_mode ? 0 : "keyboard", msg.c_str ());
-
-  std::string prompt = "debug> ";
-
-  if (nargin > 0)
-    {
-      prompt = args(0).string_value ();
-
-      if (error_state)
-       {
-         error ("input: unrecognized argument");
-         return retval;
-       }
-    }
-
- again:
+  std::string prompt = args(0).string_value ();
+
+  if (error_state)
+    {
+      error ("input: unrecognized argument");
+      return retval;
+    }
 
   flush_octave_stdout ();
 
@@ -673,43 +684,7 @@ get_user_input (const octave_value_list&
        octave_diary << "\n";
 
       if (len < 1)
-       {
-         if (Vdebugging)
-           goto again;
-         else
-           return read_as_string ? octave_value ("") : octave_value (Matrix 
());
-       }
-
-      if (Vdebugging)
-       {
-         if (match_sans_spaces_semi ("exit", input_buf)
-             || match_sans_spaces_semi ("quit", input_buf)
-             || match_sans_spaces_semi ("return", input_buf)
-             || match_sans_spaces_semi ("dbcont", input_buf))
-           {
-             return retval;
-           }
-         else if (match_sans_spaces_semi ("dbstep", input_buf))
-           {
-             tree::break_next = true;
-
-             tree::last_line = 0;
-
-             tree::break_function = octave_call_stack::current ();
-
-             return retval;
-           }
-         else if (match_sans_spaces_semi ("dbnext", input_buf))
-           {
-             tree::break_next = true;
-
-             tree::last_line = octave_call_stack::current_line ();
-
-             tree::break_function = octave_call_stack::current ();
-
-             return retval;
-           }
-       }
+       return read_as_string ? octave_value ("") : octave_value (Matrix ());
 
       if (read_as_string)
        {
@@ -723,9 +698,7 @@ get_user_input (const octave_value_list&
        {
          int parse_status = 0;
 
-         bool silent = ! Vdebugging;
-
-         retval = eval_string (input_buf, silent, parse_status, nargout);
+         retval = eval_string (input_buf, true, parse_status, nargout);
 
          if (! Vdebugging && retval.length () == 0)
            retval(0) = Matrix ();
@@ -733,19 +706,6 @@ get_user_input (const octave_value_list&
     }
   else
     error ("input: reading user-input failed!");
-
-  if (Vdebugging)
-    {
-      // Clear error_state so that if errors were encountered while
-      // evaluating user input, extra error messages will not be
-      // printed after we return.
-
-      reset_error_handler ();
-
-      retval = octave_value_list ();
-
-      goto again;
-    }
 
   return retval;
 }
@@ -895,9 +855,12 @@ do_keyboard (const octave_value_list& ar
   Vsaving_history = true;
   Vdebugging = true;
 
-  octave_value_list tmp = get_user_input (args, 0);
-
-  retval = tmp(0);
+  std::string prompt = "debug> ";
+  if (nargin > 0)
+    prompt = args(0).string_value ();
+
+  if (! error_state)
+    get_debug_input (prompt);
 
   unwind_protect::run_frame ("do_keyboard");
 
diff --git a/src/input.h b/src/input.h
--- a/src/input.h
+++ b/src/input.h
@@ -91,6 +91,12 @@ extern OCTINTERP_API bool Vdrawnow_reque
 // TRUE if we are in debugging mode.
 extern bool Vdebugging;
 
+// TRUE if we are returning from debugging mode.
+extern bool Vdebugging_return;
+
+// The current line that we are debugging
+extern int Vdebugging_current_line;
+
 extern std::string gnu_readline (const std::string& s, bool force_readline = 
false);
 
 extern void initialize_command_input (void);
diff --git a/src/parse.y b/src/parse.y
--- a/src/parse.y
+++ b/src/parse.y
@@ -2216,11 +2216,20 @@ make_return_command (token *return_tok)
   int l = return_tok->line ();
   int c = return_tok->column ();
 
-  if (lexer_flags.defining_func || reading_script_file
-      || evaluating_function_body)
-    retval = new tree_return_command (l, c);
+  if (Vdebugging)
+    {
+      Vdebugging = false;
+
+      retval = new tree_no_op_command ("return", l, c);
+    }
   else
-    retval = new tree_no_op_command ("return", l, c);
+    {
+      if (lexer_flags.defining_func || reading_script_file
+          || evaluating_function_body)
+        retval = new tree_return_command (l, c);
+      else
+        retval = new tree_no_op_command ("return", l, c);
+    }
 
   return retval;
 }
diff --git a/src/pt-bp.h b/src/pt-bp.h
--- a/src/pt-bp.h
+++ b/src/pt-bp.h
@@ -166,31 +166,40 @@ extern bool octave_debug_on_interrupt_st
       octave_function *xfcn = octave_call_stack::current (); \
  \
       if (octave_debug_on_interrupt_state \
-         || (tree::break_next && tree::last_line == 0) \
-         || (tree::break_next \
+         || (tree::break_next >= 0 && tree::last_line == 0) \
+         || (tree::break_next >= 0 \
              && xfcn == tree::break_function \
              && tree::last_line != line ()) \
          || is_breakpoint ()) \
         { \
-          octave_debug_on_interrupt_state = false; \
- \
-          tree::break_next = false; \
- \
-          if (xfcn) \
-            octave_stdout << xfcn->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 (); \
+         if (!octave_debug_on_interrupt_state && tree::break_next > 0) \
+           { \
+             tree::break_next--; \
+             if (tree::last_line > 0) \
+               tree::last_line = line(); \
+           } \
+         else \
+           { \
+              octave_debug_on_interrupt_state = false; \
+ \
+              tree::break_next = -1; \
+ \
+              if (xfcn) \
+                octave_stdout << xfcn->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 (); \
+           } \
         } \
     } \
   while (0)
diff --git a/src/pt.cc b/src/pt.cc
--- a/src/pt.cc
+++ b/src/pt.cc
@@ -33,8 +33,8 @@ along with Octave; see the file COPYING.
 #include "pt.h"
 #include "pt-pr-code.h"
 
-// If true, stop executing at the next possible point.
-bool tree::break_next = false;
+// If zero, stop executing at the next possible point.
+int tree::break_next = -1;
 
 // The line where dbnext was executed.
 int tree::last_line = 0;
diff --git a/src/pt.h b/src/pt.h
--- a/src/pt.h
+++ b/src/pt.h
@@ -66,7 +66,7 @@ public:
     { return break_point; }
 
   // If true, stop executing at the next possible point.
-  static bool break_next;
+  static int break_next;
   
   // The line where dbnext was executed.
   static int last_line; 
diff --git a/src/toplev.cc b/src/toplev.cc
--- a/src/toplev.cc
+++ b/src/toplev.cc
@@ -112,11 +112,11 @@ octave_call_stack::do_current_column (vo
 }
 
 octave_user_script *
-octave_call_stack::do_caller_user_script (void) const
+octave_call_stack::do_caller_user_script (difference_type q) const
 {
   octave_user_script *retval = 0;
 
-  for (const_iterator p = cs.begin (); p != cs.end (); p++)
+  for (const_iterator p = cs.begin () + q; p != cs.end (); p++)
     {
       const call_stack_elt& elt = *p;
 
@@ -133,11 +133,11 @@ octave_call_stack::do_caller_user_script
 }
 
 octave_user_function *
-octave_call_stack::do_caller_user_function (void) const
+octave_call_stack::do_caller_user_function (difference_type q) const
 {
   octave_user_function *retval = 0;
 
-  for (const_iterator p = cs.begin (); p != cs.end (); p++)
+  for (const_iterator p = cs.begin () + q; p != cs.end (); p++)
     {
       const call_stack_elt& elt = *p;
 
@@ -154,11 +154,11 @@ octave_call_stack::do_caller_user_functi
 }
 
 octave_user_code *
-octave_call_stack::do_caller_user_code (void) const
+octave_call_stack::do_caller_user_code (difference_type q) const
 {
   octave_user_code *retval = 0;
 
-  for (const_iterator p = cs.begin (); p != cs.end (); p++)
+  for (const_iterator p = cs.begin () + q; p != cs.end (); p++)
     {
       const call_stack_elt& elt = *p;
 
diff --git a/src/toplev.h b/src/toplev.h
--- a/src/toplev.h
+++ b/src/toplev.h
@@ -94,6 +94,7 @@ public:
 
   typedef std::deque<call_stack_elt>::iterator iterator;
   typedef std::deque<call_stack_elt>::const_iterator const_iterator;
+  typedef std::deque<call_stack_elt>::difference_type difference_type;
 
   static bool instance_ok (void)
   {
@@ -149,21 +150,21 @@ public:
   }
   
   // First script on the stack.
-  static octave_user_script *caller_script (void)
-  {
-    return instance_ok () ? instance->do_caller_user_script () : 0;
+  static octave_user_script *caller_script (difference_type q = 0)
+  {
+    return instance_ok () ? instance->do_caller_user_script (q) : 0;
   }
 
   // First user-defined function on the stack.
-  static octave_user_function *caller_user_function (void)
-  {
-    return instance_ok () ? instance->do_caller_user_function () : 0;
+  static octave_user_function *caller_user_function (difference_type q = 0)
+  {
+    return instance_ok () ? instance->do_caller_user_function (q) : 0;
   }
 
   // First user-defined function on the stack.
-  static octave_user_code *caller_user_code (void)
-  {
-    return instance_ok () ? instance->do_caller_user_code () : 0;
+  static octave_user_code *caller_user_code (difference_type q = 0)
+  {
+    return instance_ok () ? instance->do_caller_user_code (q) : 0;
   }
 
   static void
@@ -251,11 +252,11 @@ private:
     return retval;
   }
 
-  octave_user_script *do_caller_user_script (void) const;
-
-  octave_user_function *do_caller_user_function (void) const;
-
-  octave_user_code *do_caller_user_code (void) const;
+  octave_user_script *do_caller_user_script (difference_type q = 0) const;
+
+  octave_user_function *do_caller_user_function (difference_type q = 0) const;
+
+  octave_user_code *do_caller_user_code (difference_type q = 0) const; 
 
   void do_push (octave_function *f, symbol_table::scope_id scope,
                symbol_table::context_id context)

reply via email to

[Prev in Thread] Current Thread [Next in Thread]