Mercurial > hg > octave-lyh
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 +++ b/libgui/src/m-editor/file-editor-interface.h @@ -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 +++ b/libgui/src/m-editor/file-editor-tab.cc @@ -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 +++ b/libgui/src/m-editor/file-editor-tab.h @@ -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 +++ b/libgui/src/m-editor/file-editor.cc @@ -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 +++ b/libgui/src/m-editor/file-editor.h @@ -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 +++ b/libgui/src/main-window.cc @@ -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 +++ b/libgui/src/main-window.h @@ -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 +++ b/libgui/src/octave-adapter/octave-event-listener.h @@ -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 +++ b/libgui/src/octave-adapter/octave-link.cc @@ -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 +++ b/libgui/src/octave-adapter/octave-link.h @@ -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 +++ b/libgui/src/octave-adapter/octave-main-thread.cc @@ -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 +++ b/libgui/src/octave-qt-event-listener.cc @@ -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 +++ b/libgui/src/octave-qt-event-listener.h @@ -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 +++ b/libinterp/interpfcn/debug.cc @@ -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 +++ b/libinterp/interpfcn/debug.h @@ -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 +++ b/libinterp/interpfcn/input.cc @@ -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);