changeset 16395:fc491da603f6

also provide a hook for exiting debugger * file-editor-interface.h (file_editor_interface::insert_debugger_pointer_request): Rename from file_editor_interface::handle_update_debug_pointer_request (file_editor_interface::delete_debugger_pointer_request): New function. * file-editor-tab.h, file-editor-tab.cc (file_editor_tab::insert_debugger_pointer): Rename from file_editor_tab::set_debugger_position. Change all uses. (file_editor_tab::delete_debugger_pointer): New function. * file-editor.h, file-editor.cc (file_editor::handle_insert_debugger_pointer_request): Renamem from file_editor::handle_update_debug_pointer_request. Change all uses. (file_editor::handle_delete_debugger_pointer_request): New function. (file_editor::add_file_editor_tab): Connect fetab_delete_debugger_pointer signal to delete_debugger_pointer. (file_editor::fetab_insert_debugger_pointer): Rename from file_editor::fetab_set_debugger_position. Change all uses. (file_editor::fetab_delete_debugger_pointer): New signal. * main-window.h, main-window.cc (main_window::handle_insert_debugger_pointer_request): Rename from main_window::handle_update_debug_pointer_request. (main_window::handle_delete_debugger_pointer_request): New function. (main_window::construct): Connect delete_debugger_pointer_signal to handle_delete_debugger_pointer_request. * octave-event-listener.h (event_listener::insert_debugger_pointer): Rename from event_listener::update_debug_pointer): (event_listener::delete_debugger_pointer): New function * octave-link.h, octave-link.cc (octave_link::do_insert_debugger_pointer): Rename from octave_link::do_update_debug_pointer. Change all uses. (octave_link::do_delete_debugger_pointer): New function. (octave_link::do_enter_debugger_event_hook_fcn): Rename from octave_link::do_debug_input_event_hook_fcn. (octave_link::do_exit_debugger_event_hook_fcn): New function. (enter_debugger_event_hook_fcn): Rename form debug_input_event_hook_fcn. Change all uses. (octave_link::exit_debugger_event_hook_fcn): New function. * octave-main-thread.h, octave-main-thread.cc (enter_debugger_event_hook_fcn): Rename from debug_input_event_hook_fcn. (exit_debugger_event_hook_fcn): New function. (octave_main_thread::run): Install exit_debugger_event_hook_fcn hook function. * octave-qt-event-listener.h, octave-qt-event-listener.cc (octave_qt_event_listener::insert_debugger_pointer): Rename from octave_qt_event_listener::update_debug_pointer. Change all uses. (octave_qt_event_listener::delete_debugger_pointer): New function. * octave-qt-event-listener.h (octave_qt_event_listener::update_debug_pointer_signal): Rename from octave_qt_event_listener::insert_debugger_pointer_signal. Change all uses. (octave_qt_event_listner::delete_debugger_pointer_signal): New signal. * input.cc (enter_debugger_event_hook_functions): Rename from debug_input_event_hook_functions. Change all uses. (exit_debugger_event_hook_functions): New static variable. (exit_debugger_cleanup): new function. (get_debug_input): Use unwind-protect to run exit_debugger_event_hook_functions on return. (Fadd_enter_debugger_event_hook): Rename from Fadd_debug_input_event_hook. Change all uses. (Fremove_enter_debugger_event_hook): Rename from Fremove_debug_input_event_hook. Change all uses. (Fadd_exit_debugger_event_hook, Fremove_exit_debugger_event_hook): New functions.
author John W. Eaton <jwe@octave.org>
date Fri, 29 Mar 2013 22:37:01 -0400
parents a53f56e16627
children c6a13c1900fc
files libgui/src/m-editor/file-editor-interface.h libgui/src/m-editor/file-editor-tab.cc libgui/src/m-editor/file-editor-tab.h libgui/src/m-editor/file-editor.cc libgui/src/m-editor/file-editor.h libgui/src/main-window.cc libgui/src/main-window.h libgui/src/octave-adapter/octave-event-listener.h libgui/src/octave-adapter/octave-link.cc libgui/src/octave-adapter/octave-link.h libgui/src/octave-adapter/octave-main-thread.cc libgui/src/octave-qt-event-listener.cc libgui/src/octave-qt-event-listener.h libinterp/interpfcn/input.cc
diffstat 14 files changed, 293 insertions(+), 56 deletions(-) [+]
line wrap: on
line diff
--- a/libgui/src/m-editor/file-editor-interface.h	Fri Mar 29 12:14:52 2013 -0700
+++ b/libgui/src/m-editor/file-editor-interface.h	Fri Mar 29 22:37:01 2013 -0400
@@ -46,8 +46,12 @@
 
   virtual void handle_entered_debug_mode () = 0;
   virtual void handle_quit_debug_mode () = 0;
-  virtual void handle_update_debug_pointer_request (const QString& file,
-                                                    int line) = 0;
+
+  virtual void
+  handle_insert_debugger_pointer_request (const QString& file, int line) = 0;
+
+  virtual void
+  handle_delete_debugger_pointer_request (const QString& file, int line) = 0;
 
   virtual void handle_update_dbstop_marker_request (bool insert,
                                                     const QString& file,
--- a/libgui/src/m-editor/file-editor-tab.cc	Fri Mar 29 12:14:52 2013 -0700
+++ b/libgui/src/m-editor/file-editor-tab.cc	Fri Mar 29 22:37:01 2013 -0400
@@ -1133,12 +1133,11 @@
 }
 
 void
-file_editor_tab::set_debugger_position (const QWidget *ID, int line)
+file_editor_tab::insert_debugger_pointer (const QWidget *ID, int line)
 {
   if (ID != this || ID == 0)
     return;
 
-  _edit_area->markerDeleteAll (debugger_position);
   if (line > 0)
     {
       _edit_area->markerAdd (line, debugger_position);
@@ -1147,6 +1146,16 @@
 }
 
 void
+file_editor_tab::delete_debugger_pointer (const QWidget *ID, int line)
+{
+  if (ID != this || ID == 0)
+    return;
+
+  if (line > 0)
+    _edit_area->markerDelete (line, debugger_position);
+}
+
+void
 file_editor_tab::do_dbstop_marker (bool insert, const QWidget *ID, int line)
 {
   if (ID != this || ID == 0)
--- a/libgui/src/m-editor/file-editor-tab.h	Fri Mar 29 12:14:52 2013 -0700
+++ b/libgui/src/m-editor/file-editor-tab.h	Fri Mar 29 22:37:01 2013 -0400
@@ -77,7 +77,9 @@
   void find (const QWidget* ID);
   void goto_line (const QWidget* ID, int line = -1);
 
-  void set_debugger_position (const QWidget *ID, int line = -1);
+  void insert_debugger_pointer (const QWidget *ID, int line = -1);
+  void delete_debugger_pointer (const QWidget *ID, int line = -1);
+
   void do_dbstop_marker (bool insert, const QWidget *ID, int line = -1);
 
   void set_modified (bool modified = true);
--- a/libgui/src/m-editor/file-editor.cc	Fri Mar 29 12:14:52 2013 -0700
+++ b/libgui/src/m-editor/file-editor.cc	Fri Mar 29 22:37:01 2013 -0400
@@ -173,7 +173,7 @@
               emit fetab_goto_line (p->second, line);
 
               if (debug_pointer)
-                emit fetab_set_debugger_position (p->second, line-1);
+                emit fetab_insert_debugger_pointer (p->second, line-1);
 
               if (dbstop_marker)
                 emit fetab_do_dbstop_marker (insert, p->second, line-1);
@@ -201,7 +201,7 @@
                       emit fetab_goto_line (fileEditorTab, line);
 
                       if (debug_pointer)
-                        emit fetab_set_debugger_position (fileEditorTab, line-1);
+                        emit fetab_insert_debugger_pointer (fileEditorTab, line-1);
                       if (dbstop_marker)
                         emit fetab_do_dbstop_marker
                           (insert, fileEditorTab, line-1);
@@ -299,12 +299,35 @@
 }
 
 void
-file_editor::handle_update_debug_pointer_request (const QString& file, int line)
+file_editor::handle_insert_debugger_pointer_request (const QString& file, int line)
 {
   request_open_file (file, line, true);
 }
 
 void
+file_editor::handle_delete_debugger_pointer_request (const QString& file, int line)
+{
+  if (! file.isEmpty ())
+    {
+      // Have all file editor tabs signal what their file names are.
+      editor_tab_map.clear ();
+      emit fetab_file_name_query (0);
+
+      // Check whether this file is already open in the editor.
+      std::map<QString, QWidget *>::const_iterator p = editor_tab_map.find (file);
+      if (p != editor_tab_map.end ())
+        {
+          _tab_widget->setCurrentWidget (p->second);
+
+          if (line > 0)
+            emit fetab_delete_debugger_pointer (p->second, line-1);
+
+          emit fetab_set_focus (p->second);
+        }
+    }
+}
+
+void
 file_editor::handle_update_dbstop_marker_request (bool insert,
                                                   const QString& file, int line)
 {
@@ -884,8 +907,10 @@
            f, SLOT (goto_line (const QWidget *, int)));
   connect (this, SIGNAL (fetab_set_focus (const QWidget*)),
            f, SLOT (set_focus (const QWidget*)));
-  connect (this, SIGNAL (fetab_set_debugger_position (const QWidget *, int)),
-           f, SLOT (set_debugger_position (const QWidget *, int)));
+  connect (this, SIGNAL (fetab_insert_debugger_pointer (const QWidget *, int)),
+           f, SLOT (insert_debugger_pointer (const QWidget *, int)));
+  connect (this, SIGNAL (fetab_delete_debugger_pointer (const QWidget *, int)),
+           f, SLOT (delete_debugger_pointer (const QWidget *, int)));
   connect (this, SIGNAL (fetab_do_dbstop_marker (bool, const QWidget *, int)),
            f, SLOT (do_dbstop_marker (bool, const QWidget *, int)));
 
--- a/libgui/src/m-editor/file-editor.h	Fri Mar 29 12:14:52 2013 -0700
+++ b/libgui/src/m-editor/file-editor.h	Fri Mar 29 22:37:01 2013 -0400
@@ -88,7 +88,8 @@
   void fetab_uncomment_selected_text (const QWidget* ID);
   void fetab_find (const QWidget* ID);
   void fetab_goto_line (const QWidget* ID, int line = -1);
-  void fetab_set_debugger_position (const QWidget* ID, int line = -1);
+  void fetab_insert_debugger_pointer (const QWidget* ID, int line = -1);
+  void fetab_delete_debugger_pointer (const QWidget* ID, int line = -1);
   void fetab_do_dbstop_marker (bool insert, const QWidget* ID, int line = -1);
   void fetab_set_focus (const QWidget* ID);
 
@@ -130,7 +131,8 @@
   void handle_mru_add_file (const QString& file_name);
   void check_conflict_save (const QString& fileName, bool remove_on_success);
 
-  void handle_update_debug_pointer_request (const QString& file, int line);
+  void handle_insert_debugger_pointer_request (const QString& file, int line);
+  void handle_delete_debugger_pointer_request (const QString& file, int line);
   void handle_update_dbstop_marker_request (bool insert, const QString& file,
                                             int line);
 
--- a/libgui/src/main-window.cc	Fri Mar 29 12:14:52 2013 -0700
+++ b/libgui/src/main-window.cc	Fri Mar 29 22:37:01 2013 -0400
@@ -511,10 +511,18 @@
 }
 
 void
-main_window::handle_update_debug_pointer_request (const QString& file, int line)
+main_window::handle_insert_debugger_pointer_request (const QString& file, int line)
 {
 #ifdef HAVE_QSCINTILLA
-  _file_editor->handle_update_debug_pointer_request (file, line);
+  _file_editor->handle_insert_debugger_pointer_request (file, line);
+#endif
+}
+
+void
+main_window::handle_delete_debugger_pointer_request (const QString& file, int line)
+{
+#ifdef HAVE_QSCINTILLA
+  _file_editor->handle_delete_debugger_pointer_request (file, line);
 #endif
 }
 
@@ -1184,8 +1192,12 @@
            SLOT (handle_quit_debug_mode ()));
 
   connect (_octave_qt_event_listener,
-           SIGNAL (update_debug_pointer_signal (const QString&, int)), this,
-           SLOT (handle_update_debug_pointer_request (const QString&, int)));
+           SIGNAL (insert_debugger_pointer_signal (const QString&, int)), this,
+           SLOT (handle_insert_debugger_pointer_request (const QString&, int)));
+
+  connect (_octave_qt_event_listener,
+           SIGNAL (delete_debugger_pointer_signal (const QString&, int)), this,
+           SLOT (handle_delete_debugger_pointer_request (const QString&, int)));
 
   connect (_octave_qt_event_listener,
            SIGNAL (update_dbstop_marker_signal (bool, const QString&, int)),
--- a/libgui/src/main-window.h	Fri Mar 29 12:14:52 2013 -0700
+++ b/libgui/src/main-window.h	Fri Mar 29 22:37:01 2013 -0400
@@ -118,7 +118,8 @@
 
   void handle_entered_debug_mode ();
   void handle_quit_debug_mode ();
-  void handle_update_debug_pointer_request (const QString& file, int line);
+  void handle_insert_debugger_pointer_request (const QString& file, int line);
+  void handle_delete_debugger_pointer_request (const QString& file, int line);
   void handle_update_dbstop_marker_request (bool insert, const QString& file, int line);
   void debug_continue ();
   void debug_step_into ();
--- a/libgui/src/octave-adapter/octave-event-listener.h	Fri Mar 29 12:14:52 2013 -0700
+++ b/libgui/src/octave-adapter/octave-event-listener.h	Fri Mar 29 22:37:01 2013 -0400
@@ -40,7 +40,11 @@
     virtual void
     update_history (void) = 0;
 
-    virtual void update_debug_pointer (const std::string& file, int line) = 0;
+    virtual void
+    insert_debugger_pointer (const std::string& file, int line) = 0;
+
+    virtual void
+    delete_debugger_pointer (const std::string& file, int line) = 0;
 
     virtual void
     update_dbstop_marker (bool insert, const std::string& file, int line) = 0;
--- a/libgui/src/octave-adapter/octave-link.cc	Fri Mar 29 12:14:52 2013 -0700
+++ b/libgui/src/octave-adapter/octave-link.cc	Fri Mar 29 22:37:01 2013 -0400
@@ -157,7 +157,7 @@
 }
 
 void
-octave_link::do_update_debug_pointer (const octave_value_list& args)
+octave_link::do_insert_debugger_pointer (const octave_value_list& args)
 {
   if (event_listener)
     {
@@ -175,7 +175,41 @@
 
               if (! error_state)
                 {
-                  event_listener->update_debug_pointer (file, line);
+                  event_listener->insert_debugger_pointer (file, line);
+
+                  do_process_events ();
+                }
+              else
+                ::error ("invalid struct in debug pointer callback");
+            }
+          else
+            ::error ("expecting struct in debug pointer callback");
+        }
+      else
+        ::error ("invalid call to debug pointer callback");
+    }
+}
+
+void
+octave_link::do_delete_debugger_pointer (const octave_value_list& args)
+{
+  if (event_listener)
+    {
+      if (args.length () == 1)
+        {
+          octave_scalar_map m = args(0).scalar_map_value ();
+
+          if (! error_state)
+            {
+              octave_value ov_file = m.getfield ("file");
+              octave_value ov_line = m.getfield ("line");
+
+              std::string file = ov_file.string_value ();
+              int line = ov_line.int_value ();
+
+              if (! error_state)
+                {
+                  event_listener->delete_debugger_pointer (file, line);
 
                   do_process_events ();
                 }
@@ -203,9 +237,15 @@
 }
 
 void
-octave_link::do_debug_input_event_hook_fcn (const octave_value_list& args)
+octave_link::do_enter_debugger_event_hook_fcn (const octave_value_list& args)
 {
-  do_update_debug_pointer (args);
+  do_insert_debugger_pointer (args);
+}
+
+void
+octave_link::do_exit_debugger_event_hook_fcn (const octave_value_list& args)
+{
+  do_delete_debugger_pointer (args);
 }
 
 void
--- a/libgui/src/octave-adapter/octave-link.h	Fri Mar 29 12:14:52 2013 -0700
+++ b/libgui/src/octave-adapter/octave-link.h	Fri Mar 29 22:37:01 2013 -0400
@@ -146,10 +146,16 @@
       instance->do_post_input_event_hook_fcn ();
   }
 
-  static void debug_input_event_hook_fcn (const octave_value_list& args)
+  static void enter_debugger_event_hook_fcn (const octave_value_list& args)
   {
     if (instance_ok ())
-      instance->do_debug_input_event_hook_fcn (args);
+      instance->do_enter_debugger_event_hook_fcn (args);
+  }
+
+  static void exit_debugger_event_hook_fcn (const octave_value_list& args)
+  {
+    if (instance_ok ())
+      instance->do_exit_debugger_event_hook_fcn (args);
   }
 
   static void
@@ -221,11 +227,13 @@
   std::string do_last_working_directory (void);
   void do_update_workspace (void);
   void do_update_history (void);
-  void do_update_debug_pointer (const octave_value_list& args);
+  void do_insert_debugger_pointer (const octave_value_list& args);
+  void do_delete_debugger_pointer (const octave_value_list& args);
 
   void do_pre_input_event_hook_fcn (void);
   void do_post_input_event_hook_fcn (void);
-  void do_debug_input_event_hook_fcn (const octave_value_list& args);
+  void do_enter_debugger_event_hook_fcn (const octave_value_list& args);
+  void do_exit_debugger_event_hook_fcn (const octave_value_list& args);
   void do_update_breakpoint_hook_fcn (bool insert,
                                       const octave_value_list& args);
 };
--- a/libgui/src/octave-adapter/octave-main-thread.cc	Fri Mar 29 12:14:52 2013 -0700
+++ b/libgui/src/octave-adapter/octave-main-thread.cc	Fri Mar 29 22:37:01 2013 -0400
@@ -56,11 +56,21 @@
 }
 
 static octave_value_list
-debug_input_event_hook_fcn (const octave_value_list& args, int)
+enter_debugger_event_hook_fcn (const octave_value_list& args, int)
 {
   octave_value_list retval;
 
-  octave_link::debug_input_event_hook_fcn (args);
+  octave_link::enter_debugger_event_hook_fcn (args);
+
+  return retval;
+}
+
+static octave_value_list
+exit_debugger_event_hook_fcn (const octave_value_list& args, int)
+{
+  octave_value_list retval;
+
+  octave_link::exit_debugger_event_hook_fcn (args);
 
   return retval;
 }
@@ -108,9 +118,13 @@
   octave_value post_fcn_handle (new octave_fcn_handle (post_fcn));
   Fadd_post_input_event_hook (post_fcn_handle);
 
-  octave_value debug_fcn (new octave_builtin (debug_input_event_hook_fcn));
-  octave_value debug_fcn_handle (new octave_fcn_handle (debug_fcn));
-  Fadd_debug_input_event_hook (debug_fcn_handle);
+  octave_value enter_debugger_fcn (new octave_builtin (enter_debugger_event_hook_fcn));
+  octave_value enter_debugger_fcn_handle (new octave_fcn_handle (enter_debugger_fcn));
+  Fadd_enter_debugger_event_hook (enter_debugger_fcn_handle);
+
+  octave_value exit_debugger_fcn (new octave_builtin (exit_debugger_event_hook_fcn));
+  octave_value exit_debugger_fcn_handle (new octave_fcn_handle (exit_debugger_fcn));
+  Fadd_exit_debugger_event_hook (exit_debugger_fcn_handle);
 
   octave_value dbstop_fcn (new octave_builtin (dbstop_hook_fcn));
   octave_value dbstop_fcn_handle (new octave_fcn_handle (dbstop_fcn));
--- a/libgui/src/octave-qt-event-listener.cc	Fri Mar 29 12:14:52 2013 -0700
+++ b/libgui/src/octave-qt-event-listener.cc	Fri Mar 29 22:37:01 2013 -0400
@@ -54,10 +54,17 @@
 }
 
 void
-octave_qt_event_listener::update_debug_pointer (const std::string& file,
-                                                int line)
+octave_qt_event_listener::insert_debugger_pointer (const std::string& file,
+                                                   int line)
 {
-  emit update_debug_pointer_signal (QString::fromStdString (file), line);
+  emit insert_debugger_pointer_signal (QString::fromStdString (file), line);
+}
+
+void
+octave_qt_event_listener::delete_debugger_pointer (const std::string& file,
+                                                   int line)
+{
+  emit delete_debugger_pointer_signal (QString::fromStdString (file), line);
 }
 
 void
--- a/libgui/src/octave-qt-event-listener.h	Fri Mar 29 12:14:52 2013 -0700
+++ b/libgui/src/octave-qt-event-listener.h	Fri Mar 29 22:37:01 2013 -0400
@@ -37,7 +37,8 @@
   void current_directory_has_changed (const std::string& directory);
   void update_workspace (void);
   void update_history (void);
-  void update_debug_pointer (const std::string& file, int line);
+  void insert_debugger_pointer (const std::string& file, int line);
+  void delete_debugger_pointer (const std::string& file, int line);
   void update_dbstop_marker (bool insert, const std::string& file, int line);
   void about_to_exit ();
 
@@ -48,7 +49,8 @@
   void current_directory_has_changed_signal (const QString& directory);
   void update_workspace_signal (void);
   void update_history_signal (void);
-  void update_debug_pointer_signal (const QString& file, int line);
+  void insert_debugger_pointer_signal (const QString& file, int line);
+  void delete_debugger_pointer_signal (const QString& file, int line);
   void update_dbstop_marker_signal (bool insert, const QString& file, int line);
   void entered_debug_mode_signal ();
   void quit_debug_mode_signal ();
--- a/libinterp/interpfcn/input.cc	Fri Mar 29 12:14:52 2013 -0700
+++ b/libinterp/interpfcn/input.cc	Fri Mar 29 22:37:01 2013 -0400
@@ -125,7 +125,8 @@
 static hook_function_list pre_input_event_hook_functions;
 static hook_function_list input_event_hook_functions;
 static hook_function_list post_input_event_hook_functions;
-static hook_function_list debug_input_event_hook_functions;
+static hook_function_list enter_debugger_event_hook_functions;
+static hook_function_list exit_debugger_event_hook_functions;
 
 // For octave_quit.
 void
@@ -457,8 +458,16 @@
 }
 
 static void
+exit_debugger_cleanup (const octave_value& loc_info)
+{
+  exit_debugger_event_hook_functions.run (loc_info);
+}
+
+static void
 get_debug_input (const std::string& prompt)
 {
+  unwind_protect frame;
+
   octave_user_code *caller = octave_call_stack::caller_user_code ();
   std::string nm;
 
@@ -501,8 +510,11 @@
 
           if (have_file)
             {
-              debug_input_event_hook_functions.run
-                (location_info (nm, curr_debug_line));
+              octave_value loc_info = location_info (nm, curr_debug_line);
+
+              enter_debugger_event_hook_functions.run (loc_info);
+
+              frame.add_fcn (exit_debugger_cleanup, loc_info);
 
               std::string line_buf
                 = get_file_line (nm, curr_debug_line);
@@ -518,8 +530,6 @@
   if (! msg.empty ())
     std::cerr << msg << std::endl;
 
-  unwind_protect frame;
-
   frame.protect_var (VPS1);
   VPS1 = prompt;
 
@@ -1362,10 +1372,10 @@
   return retval;
 }
 
-DEFUN (add_debug_input_event_hook, args, ,
+DEFUN (add_enter_debugger_event_hook, args, ,
   "-*- texinfo -*-\n\
-@deftypefn  {Built-in Function} {@var{id} =} add_debug_input_event_hook (@var{fcn})\n\
-@deftypefnx {Built-in Function} {@var{id} =} add_debug_input_event_hook (@var{fcn}, @var{data})\n\
+@deftypefn  {Built-in Function} {@var{id} =} add_enter_debugger_event_hook (@var{fcn})\n\
+@deftypefnx {Built-in Function} {@var{id} =} add_enter_debugger_event_hook (@var{fcn}, @var{data})\n\
 Add the named function or function handle @var{fcn} to the list of\n\
 functions to call when a debugger breakpoint is reached.  The function\n\
 should have the form\n\
@@ -1388,7 +1398,7 @@
 \n\
 The returned identifier may be used to remove the function handle from\n\
 the list of input hook functions.\n\
-@seealso{remove_debug_input_event_hook}\n\
+@seealso{remove_enter_debugger_event_hook}\n\
 @end deftypefn")
 {
   octave_value retval;
@@ -1406,12 +1416,12 @@
 
       if (! error_state)
         {
-          debug_input_event_hook_functions.insert (hook_fcn.id (), hook_fcn);
+          enter_debugger_event_hook_functions.insert (hook_fcn.id (), hook_fcn);
 
           retval = hook_fcn.id ();
         }
       else
-        error ("add_debug_input_event_hook: expecting string as first arg");
+        error ("add_enter_debugger_event_hook: expecting string as first arg");
     }
   else
     print_usage ();
@@ -1419,14 +1429,14 @@
   return retval;
 }
 
-DEFUN (remove_debug_input_event_hook, args, ,
+DEFUN (remove_enter_debugger_event_hook, args, ,
   "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} remove_debug_input_event_hook (@var{name})\n\
-@deftypefnx {Built-in Function} {} remove_debug_input_event_hook (@var{fcn_id})\n\
+@deftypefn {Built-in Function} {} remove_enter_debugger_event_hook (@var{name})\n\
+@deftypefnx {Built-in Function} {} remove_enter_debugger_event_hook (@var{fcn_id})\n\
 Remove the named function or function handle with the given identifier\n\
 from the list of functions to call immediately after accepting\n\
 interactive user input.\n\
-@seealso{add_debug_input_event_hook}\n\
+@seealso{add_enter_debugger_event_hook}\n\
 @end deftypefn")
 {
   octave_value_list retval;
@@ -1442,16 +1452,113 @@
       if (! error_state)
         {
           hook_function_list::iterator p
-            = debug_input_event_hook_functions.find (hook_fcn_id);
+            = enter_debugger_event_hook_functions.find (hook_fcn_id);
 
-          if (p != debug_input_event_hook_functions.end ())
-            debug_input_event_hook_functions.erase (p);
+          if (p != enter_debugger_event_hook_functions.end ())
+            enter_debugger_event_hook_functions.erase (p);
           else if (warn)
-            warning ("remove_debug_input_event_hook: %s not found in list",
+            warning ("remove_enter_debugger_event_hook: %s not found in list",
                      hook_fcn_id.c_str ());
         }
       else
-        error ("remove_debug_input_event_hook: argument not valid as a hook function name or id");
+        error ("remove_enter_debugger_event_hook: argument not valid as a hook function name or id");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (add_exit_debugger_event_hook, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn  {Built-in Function} {@var{id} =} add_exit_debugger_event_hook (@var{fcn})\n\
+@deftypefnx {Built-in Function} {@var{id} =} add_exit_debugger_event_hook (@var{fcn}, @var{data})\n\
+Add the named function or function handle @var{fcn} to the list of\n\
+functions to call when continuing execution after a debugger breakpoint.\n\
+The function should have the form\n\
+\n\
+@example\n\
+@var{fcn} (@var{location}, @var{data})\n\
+@end example\n\
+\n\
+in which @var{location} is a structure containing the following elements:\n\
+\n\
+@table @code\n\
+@item file\n\
+The name of the file where the breakpoint is located.\n\
+@item line\n\
+The line number corresponding to the breakpoint.\n\
+@end table\n\
+\n\
+If @var{data} is omitted when the hook function is added, the hook\n\
+function is called with a single argument.\n\
+\n\
+The returned identifier may be used to remove the function handle from\n\
+the list of input hook functions.\n\
+@seealso{remove_exit_debugger_event_hook}\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1 || nargin == 2)
+    {
+      octave_value user_data;
+
+      if (nargin == 2)
+        user_data = args(1);
+
+      hook_function hook_fcn (args(0), user_data);
+
+      if (! error_state)
+        {
+          exit_debugger_event_hook_functions.insert (hook_fcn.id (), hook_fcn);
+
+          retval = hook_fcn.id ();
+        }
+      else
+        error ("add_exit_debugger_event_hook: expecting string as first arg");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (remove_exit_debugger_event_hook, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {} remove_exit_debugger_event_hook (@var{name})\n\
+@deftypefnx {Built-in Function} {} remove_exit_debugger_event_hook (@var{fcn_id})\n\
+Remove the named function or function handle with the given identifier\n\
+from the list of functions to call immediately after accepting\n\
+interactive user input.\n\
+@seealso{add_exit_debugger_event_hook}\n\
+@end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1 || nargin == 2)
+    {
+      std::string hook_fcn_id = args(0).string_value ();
+
+      bool warn = (nargin < 2);
+
+      if (! error_state)
+        {
+          hook_function_list::iterator p
+            = exit_debugger_event_hook_functions.find (hook_fcn_id);
+
+          if (p != exit_debugger_event_hook_functions.end ())
+            exit_debugger_event_hook_functions.erase (p);
+          else if (warn)
+            warning ("remove_exit_debugger_event_hook: %s not found in list",
+                     hook_fcn_id.c_str ());
+        }
+      else
+        error ("remove_exit_debugger_event_hook: argument not valid as a hook function name or id");
     }
   else
     print_usage ();