changeset 16386:4902484f9181

callbacks to set markers in editor using command line dbstop function * debug.h, debug.cc (location_info): New function. * input.cc (get_debug_input): Use it to pass location info to hook functions. * debug.cc (bp_table::do_add_breakpoint): Likewise. (bp_table::do_remove_all_breakpoints_in_file): Likewise. (bp_table::do_remove_breakpoint): Likewise. (Fadd_dbstop_hook, Fremove_dbstop_hook, Fadd_dbclear_hook, Fremove_dbclear_hook): New functions. (dbstop_hook_functions, dbclear_hook_functions): New static variables. * file-editor-interface.h (file_editor_interface::handle_update_dbstop_marker_request): New pure virtual function. (file_editor_interface::request_open_file): New args, dbstop_marker and insert. * file-editor.h, file-editor.cc (file_editor::request_open_file): Likewise. Emit signal to set or remove dbstop marker. (file_editor::handle_update_dbstop_marker_request): New function. (file_editor::fetab_do_dbstop_marker): New signal. (file_editor::add_file_editor_tab): Connect fetab_do_dbstop_marker signal to do_dbstop_marker. * file-editor-tab.h, file-editor-tab.cc (file_editor_tab::do_dbstop_marker): New function. * file-editor-tab.cc (file_editor::goto_line): Eliminate shadowing variable declaration. * main-window.h, main-window.cc (main_window::handle_update_dbstop_marker_request): New function. (main_window::construct): Connect update_dbstop_marker_signal signal to handle_update_dbstop_marker_request. * octave-event-listener.h (event_listener::update_dbstop_marker): New pure virtual function. * octave-link.h, octave-link.cc (octave_link::update_breakpoint_hook_fcn, octave_link::do_update_breakpoint_hook_fcn): New functions. (octave_link::do_update_debug_pointer): Improve error messages. * octave-main-thread.cc (dbstop_hook_fcn, dbclear_hook_fcn): New functions. (octave_main_thread::octave_main_thread): Install hook functions for for dbstop and dbclear hooks. * octave-qt-event-listener.h, octave-qt-event-listener.cc (octave_qt_event_listener::update_dbstop_marker): New fucntion. (octave_qt_event_listener::update_dbstop_marker_signal): New signal.
author John W. Eaton <jwe@octave.org>
date Thu, 28 Mar 2013 03:20:25 -0400
parents a1690c3e93eb
children f3c93e387865
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/debug.cc libinterp/interpfcn/debug.h libinterp/interpfcn/input.cc
diffstat 16 files changed, 389 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/libgui/src/m-editor/file-editor-interface.h	Thu Mar 28 02:52:18 2013 -0400
+++ b/libgui/src/m-editor/file-editor-interface.h	Thu Mar 28 03:20:25 2013 -0400
@@ -46,15 +46,21 @@
 
   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_update_debug_pointer_request (const QString& file,
+                                                    int line) = 0;
+
+  virtual void handle_update_dbstop_marker_request (bool insert,
+                                                    const QString& file,
+                                                    int line) = 0;
   virtual void set_focus () = 0;
 
 public slots:
   virtual void request_new_file () = 0;
   virtual void request_open_file () = 0;
-  virtual void request_open_file (const QString& fileName, int line = -1,
-                                  bool set_marker = false) = 0;
-
+  virtual void request_open_file (const QString& openFileName, int line = -1,
+                                  bool debug_pointer = false,
+                                  bool dbstop_marker = false,
+                                  bool insert = true) = 0;
 //signals:
 
 //protected:
--- a/libgui/src/m-editor/file-editor-tab.cc	Thu Mar 28 02:52:18 2013 -0400
+++ b/libgui/src/m-editor/file-editor-tab.cc	Thu Mar 28 03:20:25 2013 -0400
@@ -638,7 +638,7 @@
 
   if (line <= 0)
     {
-      bool ok = false;
+      ok = false;
 
       int index;
 
@@ -1159,4 +1159,19 @@
     }
 }
 
+void
+file_editor_tab::do_dbstop_marker (bool insert, const QWidget *ID, int line)
+{
+  if (ID != this || ID == 0)
+    return;
+
+  if (line > 0)
+    {
+      if (insert)
+        _edit_area->markerAdd (line, breakpoint);
+      else
+        _edit_area->markerDelete (line, breakpoint);
+    }
+}
+
 #endif
--- a/libgui/src/m-editor/file-editor-tab.h	Thu Mar 28 02:52:18 2013 -0400
+++ b/libgui/src/m-editor/file-editor-tab.h	Thu Mar 28 03:20:25 2013 -0400
@@ -78,6 +78,7 @@
   void goto_line (const QWidget* ID, int line = -1);
 
   void set_debugger_position (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	Thu Mar 28 02:52:18 2013 -0400
+++ b/libgui/src/m-editor/file-editor.cc	Thu Mar 28 03:20:25 2013 -0400
@@ -148,7 +148,8 @@
 
 void
 file_editor::request_open_file (const QString& openFileName, int line,
-                                bool set_marker)
+                                bool debug_pointer,
+                                bool dbstop_marker, bool insert)
 {
   if (openFileName.isEmpty ())
     {
@@ -171,8 +172,11 @@
             {
               emit fetab_goto_line (p->second, line);
 
-              if (set_marker)
+              if (debug_pointer)
                 emit fetab_set_debugger_position (p->second, line-1);
+
+              if (dbstop_marker)
+                emit fetab_do_dbstop_marker (insert, p->second, line-1);
             }
 
           emit fetab_set_focus (p->second);
@@ -196,8 +200,11 @@
                     {
                       emit fetab_goto_line (fileEditorTab, line);
 
-                      if (set_marker)
+                      if (debug_pointer)
                         emit fetab_set_debugger_position (fileEditorTab, line-1);
+                      if (dbstop_marker)
+                        emit fetab_do_dbstop_marker
+                          (insert, fileEditorTab, line-1);
                     }
                 }
               else
@@ -298,6 +305,13 @@
 }
 
 void
+file_editor::handle_update_dbstop_marker_request (bool insert,
+                                                  const QString& file, int line)
+{
+  request_open_file (file, line, false, true, insert);
+}
+
+void
 file_editor::request_undo ()
 {
   emit fetab_undo (_tab_widget->currentWidget ());
@@ -870,6 +884,8 @@
            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_do_dbstop_marker (bool, const QWidget *, int)),
+           f, SLOT (do_dbstop_marker (bool, const QWidget *, int)));
 
   _tab_widget->setCurrentWidget (f);
 }
--- a/libgui/src/m-editor/file-editor.h	Thu Mar 28 02:52:18 2013 -0400
+++ b/libgui/src/m-editor/file-editor.h	Thu Mar 28 03:20:25 2013 -0400
@@ -89,6 +89,7 @@
   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_do_dbstop_marker (bool insert, const QWidget* ID, int line = -1);
   void fetab_set_focus (const QWidget* ID);
 
 public slots:
@@ -130,12 +131,16 @@
   void check_conflict_save (const QString& fileName, bool remove_on_success);
 
   void handle_update_debug_pointer_request (const QString& file, int line);
+  void handle_update_dbstop_marker_request (bool insert, const QString& file,
+                                            int line);
 
   /** Tells the editor to react on changed settings. */
   void notice_settings ();
 
 private slots:
-  void request_open_file (const QString& fileName, int line = -1, bool = false);
+  void request_open_file (const QString& fileName, int line = -1,
+                          bool debug_pointer = false,
+                          bool dbstop_marker = false, bool insert = true);
 
 private:
   void construct ();
--- a/libgui/src/main-window.cc	Thu Mar 28 02:52:18 2013 -0400
+++ b/libgui/src/main-window.cc	Thu Mar 28 03:20:25 2013 -0400
@@ -518,6 +518,15 @@
 }
 
 void
+main_window::handle_update_dbstop_marker_request (bool insert,
+                                                  const QString& file, int line)
+{
+#ifdef HAVE_QSCINTILLA
+  _file_editor->handle_update_dbstop_marker_request (insert, file, line);
+#endif
+}
+
+void
 main_window::debug_continue ()
 {
   octave_link::post_event (this, &main_window::debug_continue_callback);
@@ -1176,6 +1185,11 @@
   connect (_octave_qt_event_listener,
            SIGNAL (update_debug_pointer_signal (const QString&, int)), this,
            SLOT (handle_update_debug_pointer_request (const QString&, int)));
+
+  connect (_octave_qt_event_listener,
+           SIGNAL (update_dbstop_marker_signal (bool, const QString&, int)),
+           this,
+           SLOT (handle_update_dbstop_marker_request (bool, const QString&, int)));
 }
 
 void
--- a/libgui/src/main-window.h	Thu Mar 28 02:52:18 2013 -0400
+++ b/libgui/src/main-window.h	Thu Mar 28 03:20:25 2013 -0400
@@ -119,6 +119,7 @@
   void handle_entered_debug_mode ();
   void handle_quit_debug_mode ();
   void handle_update_debug_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 ();
   void debug_step_over ();
--- a/libgui/src/octave-adapter/octave-event-listener.h	Thu Mar 28 02:52:18 2013 -0400
+++ b/libgui/src/octave-adapter/octave-event-listener.h	Thu Mar 28 03:20:25 2013 -0400
@@ -42,6 +42,9 @@
 
     virtual void update_debug_pointer (const std::string& file, int line) = 0;
 
+    virtual void
+    update_dbstop_marker (bool insert, const std::string& file, int line) = 0;
+
     virtual void about_to_exit () = 0;
 
     virtual void entered_debug_mode () = 0;
--- a/libgui/src/octave-adapter/octave-link.cc	Thu Mar 28 02:52:18 2013 -0400
+++ b/libgui/src/octave-adapter/octave-link.cc	Thu Mar 28 03:20:25 2013 -0400
@@ -180,13 +180,13 @@
                   do_process_events ();
                 }
               else
-                ::error ("invalid struct in dbstop callback");
+                ::error ("invalid struct in debug pointer callback");
             }
           else
-            ::error ("expecting struct in dbstop callback");
+            ::error ("expecting struct in debug pointer callback");
         }
       else
-        ::error ("invalid call to dbstop callback");
+        ::error ("invalid call to debug pointer callback");
     }
 }
 
@@ -208,6 +208,41 @@
   do_update_debug_pointer (args);
 }
 
+void
+octave_link::do_update_breakpoint_hook_fcn
+  (bool insert, 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->update_dbstop_marker (insert, file, line);
+
+                  do_process_events ();
+                }
+              else
+                ::error ("invalid struct in dbstop marker callback");
+            }
+          else
+            ::error ("expecting struct in dbstop marker callback");
+        }
+      else
+        ::error ("invalid call to dbstop marker callback");
+    }
+}
+
 bool
 octave_link::instance_ok (void)
 {
--- a/libgui/src/octave-adapter/octave-link.h	Thu Mar 28 02:52:18 2013 -0400
+++ b/libgui/src/octave-adapter/octave-link.h	Thu Mar 28 03:20:25 2013 -0400
@@ -152,6 +152,13 @@
       instance->do_debug_input_event_hook_fcn (args);
   }
 
+  static void
+  update_breakpoint_hook_fcn (bool insert, const octave_value_list& args)
+  {
+    if (instance_ok ())
+      instance->do_update_breakpoint_hook_fcn (insert, args);
+  }
+
 private:
 
   static octave_link *instance;
@@ -219,6 +226,8 @@
   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_update_breakpoint_hook_fcn (bool insert,
+                                      const octave_value_list& args);
 };
 
 #endif // OCTAVELINK_H
--- a/libgui/src/octave-adapter/octave-main-thread.cc	Thu Mar 28 02:52:18 2013 -0400
+++ b/libgui/src/octave-adapter/octave-main-thread.cc	Thu Mar 28 03:20:25 2013 -0400
@@ -65,6 +65,26 @@
   return retval;
 }
 
+static octave_value_list
+dbstop_hook_fcn (const octave_value_list& args, int)
+{
+  octave_value_list retval;
+
+  octave_link::update_breakpoint_hook_fcn (true, args);
+
+  return retval;
+}
+
+static octave_value_list
+dbclear_hook_fcn (const octave_value_list& args, int)
+{
+  octave_value_list retval;
+
+  octave_link::update_breakpoint_hook_fcn (false, args);
+
+  return retval;
+}
+
 octave_main_thread::octave_main_thread () : QThread ()
 {
 }
@@ -92,6 +112,14 @@
   octave_value debug_fcn_handle (new octave_fcn_handle (debug_fcn));
   Fadd_debug_input_event_hook (debug_fcn_handle);
 
+  octave_value dbstop_fcn (new octave_builtin (dbstop_hook_fcn));
+  octave_value dbstop_fcn_handle (new octave_fcn_handle (dbstop_fcn));
+  Fadd_dbstop_hook (dbstop_fcn_handle);
+
+  octave_value dbclear_fcn (new octave_builtin (dbclear_hook_fcn));
+  octave_value dbclear_fcn_handle (new octave_fcn_handle (dbclear_fcn));
+  Fadd_dbclear_hook (dbclear_fcn_handle);
+
   // Prime the history list.
   octave_link::update_history ();
 
--- a/libgui/src/octave-qt-event-listener.cc	Thu Mar 28 02:52:18 2013 -0400
+++ b/libgui/src/octave-qt-event-listener.cc	Thu Mar 28 03:20:25 2013 -0400
@@ -61,6 +61,15 @@
 }
 
 void
+octave_qt_event_listener::update_dbstop_marker (bool insert,
+                                                const std::string& file,
+                                                int line)
+{
+  emit update_dbstop_marker_signal (insert, QString::fromStdString (file),
+                                    line);
+}
+
+void
 octave_qt_event_listener::about_to_exit ()
 {
   qApp->quit ();
--- a/libgui/src/octave-qt-event-listener.h	Thu Mar 28 02:52:18 2013 -0400
+++ b/libgui/src/octave-qt-event-listener.h	Thu Mar 28 03:20:25 2013 -0400
@@ -38,6 +38,7 @@
   void update_workspace (void);
   void update_history (void);
   void update_debug_pointer (const std::string& file, int line);
+  void update_dbstop_marker (bool insert, const std::string& file, int line);
   void about_to_exit ();
 
   void entered_debug_mode ();
@@ -48,6 +49,7 @@
   void update_workspace_signal (void);
   void update_history_signal (void);
   void update_debug_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/debug.cc	Thu Mar 28 02:52:18 2013 -0400
+++ b/libinterp/interpfcn/debug.cc	Thu Mar 28 03:20:25 2013 -0400
@@ -37,6 +37,7 @@
 #include "defun.h"
 #include "error.h"
 #include "help.h"
+#include "hook-fcn.h"
 #include "input.h"
 #include "pager.h"
 #include "oct-obj.h"
@@ -185,6 +186,17 @@
   return dbg_fcn;
 }
 
+octave_value
+location_info (const std::string& fname, int line)
+{
+  octave_scalar_map location_info_map;
+
+  location_info_map.setfield ("file", fname);
+  location_info_map.setfield ("line", line);
+
+  return octave_value (location_info_map);
+}
+
 static void
 parse_dbfunction_params (const char *who, const octave_value_list& args,
                          std::string& symbol_name, bp_table::intmap& lines)
@@ -273,6 +285,201 @@
   return retval;
 }
 
+static hook_function_list dbstop_hook_functions;
+static hook_function_list dbclear_hook_functions;
+
+DEFUN (add_dbstop_hook, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn  {Built-in Function} {@var{id} =} add_dbstop_hook (@var{fcn})\n\
+@deftypefnx {Built-in Function} {@var{id} =} add_dbstop_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 set.  The function\n\
+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_dbstop_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)
+        {
+          dbstop_hook_functions.insert (hook_fcn.id (), hook_fcn);
+
+          retval = hook_fcn.id ();
+        }
+      else
+        error ("add_dbstop_hook: expecting string as first arg");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (remove_dbstop_hook, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {} remove_dbstop_hook (@var{name})\n\
+@deftypefnx {Built-in Function} {} remove_dbstop_hook (@var{fcn_id})\n\
+Remove the named function or function handle with the given identifier\n\
+from the list of functions to call when a debugger breakpoint is set.\n\
+@seealso{add_dbstop_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
+            = dbstop_hook_functions.find (hook_fcn_id);
+
+          if (p != dbstop_hook_functions.end ())
+            dbstop_hook_functions.erase (p);
+          else if (warn)
+            warning ("remove_dbstop_hook: %s not found in list",
+                     hook_fcn_id.c_str ());
+        }
+      else
+        error ("remove_dbstop_hook: argument not valid as a hook function name or id");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (add_dbclear_hook, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn  {Built-in Function} {@var{id} =} add_dbclear_hook (@var{fcn})\n\
+@deftypefnx {Built-in Function} {@var{id} =} add_dbclear_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 cleared.  The function\n\
+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_dbclear_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)
+        {
+          dbclear_hook_functions.insert (hook_fcn.id (), hook_fcn);
+
+          retval = hook_fcn.id ();
+        }
+      else
+        error ("add_dbclear_hook: expecting string as first arg");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (remove_dbclear_hook, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {} remove_dbclear_hook (@var{name})\n\
+@deftypefnx {Built-in Function} {} remove_dbclear_hook (@var{fcn_id})\n\
+Remove the named function or function handle with the given identifier\n\
+from the list of functions to call when a debugger breakpoint is cleared.\n\
+@seealso{add_dbclear_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
+            = dbclear_hook_functions.find (hook_fcn_id);
+
+          if (p != dbclear_hook_functions.end ())
+            dbclear_hook_functions.erase (p);
+          else if (warn)
+            warning ("remove_dbclear_hook: %s not found in list",
+                     hook_fcn_id.c_str ());
+        }
+      else
+        error ("remove_dbclear_hook: argument not valid as a hook function name or id");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
 bp_table::intmap
 bp_table::do_add_breakpoint (const std::string& fname,
                              const bp_table::intmap& line)
@@ -302,6 +509,12 @@
                   if (retval[i] != 0)
                     {
                       bp_set.insert (fname);
+
+                      std::string file = dbg_fcn->fcn_file_name ();
+
+                      if (! file.empty ())
+                        dbstop_hook_functions.run
+                          (location_info (file, retval[i]));
                     }
                 }
             }
@@ -335,6 +548,8 @@
 
       if (dbg_fcn)
         {
+          std::string file = dbg_fcn->fcn_file_name ();
+
           tree_statement_list *cmds = dbg_fcn->body ();
 
           if (cmds)
@@ -348,7 +563,15 @@
                       const_intmap_iterator p = line.find (i);
 
                       if (p != line.end ())
-                        cmds->delete_breakpoint (p->second);
+                        {
+                          int lineno = p->second;
+
+                          cmds->delete_breakpoint (lineno);
+
+                          if (! file.empty ())
+                            dbclear_hook_functions.run
+                              (location_info (file, lineno));
+                        }
                     }
 
                   results = cmds->list_breakpoints ();
@@ -356,7 +579,6 @@
                   bp_set_iterator it = bp_set.find (fname);
                   if (results.length () == 0 && it != bp_set.end ())
                     bp_set.erase (it);
-
                 }
 
               retval = results.length ();
@@ -382,6 +604,8 @@
 
   if (dbg_fcn)
     {
+      std::string file = dbg_fcn->fcn_file_name ();
+
       tree_statement_list *cmds = dbg_fcn->body ();
 
       if (cmds)
@@ -393,12 +617,14 @@
               int lineno = static_cast<int> (bkpts(i).int_value ());
               cmds->delete_breakpoint (lineno);
               retval[i] = lineno;
+
+              if (! file.empty ())
+                dbclear_hook_functions.run (location_info (file, lineno));
             }
 
           bp_set_iterator it = bp_set.find (fname);
           if (it != bp_set.end ())
             bp_set.erase (it);
-
         }
     }
   else if (! silent)
--- a/libinterp/interpfcn/debug.h	Thu Mar 28 02:52:18 2013 -0400
+++ b/libinterp/interpfcn/debug.h	Thu Mar 28 03:20:25 2013 -0400
@@ -131,4 +131,6 @@
 
 extern std::string get_file_line (const std::string& fname, size_t line);
 
+extern octave_value location_info (const std::string& fname, int line);
+
 #endif
--- a/libinterp/interpfcn/input.cc	Thu Mar 28 02:52:18 2013 -0400
+++ b/libinterp/interpfcn/input.cc	Thu Mar 28 03:20:25 2013 -0400
@@ -501,14 +501,8 @@
 
           if (have_file)
             {
-              octave_scalar_map location_info_map;
-
-              location_info_map.setfield ("file", nm);
-              location_info_map.setfield ("line", curr_debug_line);
-
-              octave_value location_info (location_info_map);
-
-              debug_input_event_hook_functions.run (location_info);
+              debug_input_event_hook_functions.run
+                (location_info (nm, curr_debug_line));
 
               std::string line_buf
                 = get_file_line (nm, curr_debug_line);