Mercurial > hg > octave-lojdl
changeset 15406:0b4626dc4d38
Merge in Ed's changes
author | Jordi Gutiérrez Hermoso <jordigh@octave.org> |
---|---|
date | Tue, 18 Sep 2012 08:41:27 -0400 |
parents | 6d4cd994ea71 (current diff) f52a62a6db3a (diff) |
children | 057beb799f13 |
files | libgui/src/octave-adapter/octave-event-observer.h libgui/src/octave-adapter/octave-event.cc libgui/src/octave-adapter/octave-event.h |
diffstat | 32 files changed, 1020 insertions(+), 1181 deletions(-) [+] |
line wrap: on
line diff
--- a/libgui/src/history-dockwidget.cc +++ b/libgui/src/history-dockwidget.cc @@ -26,75 +26,21 @@ #include <QVBoxLayout> -#include "cmd-hist.h" - #include "error.h" +#include "cmd-hist.h" + #include "history-dockwidget.h" +#include "octave-link.h" history_dock_widget::history_dock_widget (QWidget * p) - : QDockWidget (p), octave_event_observer () + : QDockWidget (p) { setObjectName ("HistoryDockWidget"); construct (); } void -history_dock_widget::handle_event (octave_event *e, bool accept) -{ - static bool scroll_window = false; - - if (accept) - { - if (dynamic_cast <octave_update_history_event*> (e)) - { - // Determine the client's (our) history length and the one of the server. - int clientHistoryLength = _history_model->rowCount (); - int serverHistoryLength = command_history::length (); - - // If were behind the server, iterate through all new entries and add - // them to our history. - if (clientHistoryLength < serverHistoryLength) - { - int elts_to_add = serverHistoryLength - clientHistoryLength; - - _history_model->insertRows (clientHistoryLength, elts_to_add); - - for (int i = clientHistoryLength; i < serverHistoryLength; i++) - { - std::string entry = command_history::get_entry (i); - - _history_model->setData (_history_model->index (i), - QString::fromStdString (entry)); - } - - // FIXME -- does this behavior make sense? Calling - // _history_list_view->scrollToBottom () here doesn't seem to - // have any effect. Instead, we need to request that action - // and wait until the next event occurs in which no items - // are added to the history list. - - scroll_window = true; - } - else if (scroll_window) - { - scroll_window = false; - - _history_list_view->scrollToBottom (); - } - } - - // Post a new update event in a given time. This prevents flooding the - // event queue. - _update_history_model_timer.start (); - } - else - { - // octave_event::perform failed to handle event. - } -} - -void history_dock_widget::construct () { _history_model = new QStringListModel (); @@ -161,7 +107,7 @@ void history_dock_widget::request_history_model_update () { - octave_link::post_event (new octave_update_history_event (*this)); + octave_link::post_event (this, &history_dock_widget::update_history_callback); } void @@ -176,3 +122,48 @@ emit active_changed (false); QDockWidget::closeEvent (e); } + +void +history_dock_widget::update_history_callback (void) +{ + static bool scroll_window = false; + + // Determine the client's (our) history length and the one of the server. + int clientHistoryLength = _history_model->rowCount (); + int serverHistoryLength = command_history::length (); + + // If were behind the server, iterate through all new entries and add + // them to our history. + if (clientHistoryLength < serverHistoryLength) + { + int elts_to_add = serverHistoryLength - clientHistoryLength; + + _history_model->insertRows (clientHistoryLength, elts_to_add); + + for (int i = clientHistoryLength; i < serverHistoryLength; i++) + { + std::string entry = command_history::get_entry (i); + + _history_model->setData (_history_model->index (i), + QString::fromStdString (entry)); + } + + // FIXME -- does this behavior make sense? Calling + // _history_list_view->scrollToBottom () here doesn't seem to + // have any effect. Instead, we need to request that action + // and wait until the next event occurs in which no items + // are added to the history list. + + scroll_window = true; + } + else if (scroll_window) + { + scroll_window = false; + + _history_list_view->scrollToBottom (); + } + + // Post a new update event in a given time. This prevents flooding the + // event queue. + _update_history_model_timer.start (); +}
--- a/libgui/src/history-dockwidget.h +++ b/libgui/src/history-dockwidget.h @@ -30,17 +30,12 @@ #include <QStringListModel> #include <QTimer> -#include "octave-link.h" -#include "octave-event-observer.h" - -class history_dock_widget : public QDockWidget, public octave_event_observer +class history_dock_widget : public QDockWidget { Q_OBJECT public: history_dock_widget (QWidget *parent = 0); - void handle_event (octave_event *e, bool accept); - public slots: void handle_visibility_changed (bool visible); void request_history_model_update (); @@ -69,6 +64,8 @@ QStringListModel *_history_model; QTimer _update_history_model_timer; + + void update_history_callback (void); }; #endif // HISTORYDOCKWIDGET_H
--- a/libgui/src/m-editor/file-editor-tab.cc +++ b/libgui/src/m-editor/file-editor-tab.cc @@ -24,12 +24,6 @@ #include <config.h> #endif -#include "file-editor-tab.h" -#include "file-editor.h" -#include "find-dialog.h" -#include "octave-link.h" - - #include <Qsci/qsciapis.h> // Not available in the Debian repos yet! // #include <Qsci/qscilexeroctave.h> @@ -46,8 +40,16 @@ #include <QTextStream> #include <QVBoxLayout> +#include "file-editor-tab.h" +#include "file-editor.h" +#include "find-dialog.h" +#include "octave-link.h" + +#include "debug.h" +#include "oct-env.h" + file_editor_tab::file_editor_tab(file_editor *fileEditor) - : QWidget ((QWidget*)fileEditor), octave_event_observer () + : QWidget ((QWidget*)fileEditor) { _file_editor = fileEditor; _file_name = ""; @@ -116,44 +118,6 @@ } void -file_editor_tab::handle_event (octave_event *e, bool accept) -{ - if (accept) - { - if (dynamic_cast<octave_run_file_event*> (e)) - { - // File was run successfully. - } - - if (octave_add_breakpoint_event *abe - = dynamic_cast<octave_add_breakpoint_event*> (e)) - { - // TODO: Check file. - _edit_area->markerAdd (abe->get_line (), breakpoint); - } - - if (octave_remove_breakpoint_event *rbe - = dynamic_cast<octave_remove_breakpoint_event*> (e)) - { - // TODO: Check file. - _edit_area->markerDelete (rbe->get_line (), breakpoint); - } - - if (dynamic_cast<octave_remove_all_breakpoints_event*> (e)) - { - _edit_area->markerDeleteAll (breakpoint); - } - } - else - { - if (dynamic_cast<octave_run_file_event*> (e)) - { - // Running file failed. - } - } -} - -void file_editor_tab::closeEvent (QCloseEvent *e) { if (_file_editor->get_main_window ()->is_closing ()) @@ -307,9 +271,10 @@ // We have to cut off the suffix, because octave appends it. function_name.chop (file_info.suffix ().length () + 1); - octave_link::post_event (new octave_add_breakpoint_event - (*this, path.toStdString (), - function_name.toStdString (), line)); + bp_info info (path, function_name, line); + + octave_link::post_event + (this, &file_editor_tab::add_breakpoint_callback, info); } void @@ -322,9 +287,10 @@ // We have to cut off the suffix, because octave appends it. function_name.chop (file_info.suffix ().length () + 1); - octave_link::post_event (new octave_remove_breakpoint_event - (*this, path.toStdString (), - function_name.toStdString (), line)); + bp_info info (path, function_name, line); + + octave_link::post_event + (this, &file_editor_tab::remove_breakpoint_callback, info); } void @@ -492,9 +458,10 @@ // We have to cut off the suffix, because octave appends it. function_name.chop (file_info.suffix ().length () + 1); - octave_link::post_event (new octave_remove_all_breakpoints_event - (*this, path.toStdString (), - function_name.toStdString ())); + bp_info info (path, function_name, 0); + + octave_link::post_event + (this, &file_editor_tab::remove_all_breakpoints_callback, info); } void @@ -749,8 +716,8 @@ _file_editor->terminal ()->sendText (QString ("cd \'%1\'\n%2\n") .arg(path).arg (function_name)); // TODO: Sending a run event crashes for long scripts. Find out why. - // octave_link::post_event (new octave_run_file_event - // (*this, _file_name.toStdString ())); + // octave_link::post_event + // (this, &file_editor_tab::run_file_callback, _file_name.toStdString ())); } void @@ -839,3 +806,61 @@ update_window_title (false); } + +void +file_editor_tab::run_file_callback (void) +{ + // Maybe someday we will do something here? +} + +void +file_editor_tab::add_breakpoint_callback (const bp_info& info) +{ + bp_table::intmap intmap; + intmap[0] = info.line + 1; + + std::string previous_directory = octave_env::get_current_directory (); + octave_env::chdir (info.path); + intmap = bp_table::add_breakpoint (info.function_name, intmap); + octave_env::chdir (previous_directory); + + if (intmap.size () > 0) + { + // FIXME -- Check file. + _edit_area->markerAdd (info.line, breakpoint); + } +} + +void +file_editor_tab::remove_breakpoint_callback (const bp_info& info) +{ + bp_table::intmap intmap; + intmap[0] = info.line; + + std::string previous_directory = octave_env::get_current_directory (); + octave_env::chdir (info.path); + bp_table::remove_breakpoint (info.function_name, intmap); + octave_env::chdir (previous_directory); + + // FIXME -- check result + bool success = true; + + if (success) + { + // FIXME -- check file. + _edit_area->markerDelete (info.line, breakpoint); + } +} + +void +file_editor_tab::remove_all_breakpoints_callback (const bp_info& info) +{ + bp_table::intmap intmap; + std::string previous_directory = octave_env::get_current_directory (); + octave_env::chdir (info.path); + intmap = bp_table::remove_all_breakpoints_in_file (info.function_name, true); + octave_env::chdir (previous_directory); + + if (intmap.size() > 0) + _edit_area->markerDeleteAll (breakpoint); +}
--- a/libgui/src/m-editor/file-editor-tab.h +++ b/libgui/src/m-editor/file-editor-tab.h @@ -27,18 +27,15 @@ #include <QWidget> #include <QCloseEvent> #include <QFileSystemWatcher> -#include "octave-event-observer.h" class file_editor; -class file_editor_tab : public QWidget, public octave_event_observer +class file_editor_tab : public QWidget { Q_OBJECT public: file_editor_tab (file_editor *fileEditor); bool copy_available (); - void handle_event (octave_event *e, bool accept); - public slots: void update_window_title(bool modified); void handle_copy_available(bool enableCopy); @@ -87,6 +84,18 @@ void set_file_name (const QString& fileName); private: + + struct bp_info + { + bp_info (const QString& p, const QString& fn, int l) + : path (p.toStdString ()), function_name (fn.toStdString ()), line (l) + { } + + std::string path; + std::string function_name; + int line; + }; + void update_lexer (); void request_add_breakpoint (int line); void request_remove_breakpoint (int line); @@ -95,6 +104,11 @@ int check_file_modified (const QString& msg, int cancelButton); void do_comment_selected_text (bool comment); + void run_file_callback (void); + void add_breakpoint_callback (const bp_info& info); + void remove_breakpoint_callback (const bp_info& info); + void remove_all_breakpoints_callback (const bp_info& info); + file_editor * _file_editor; QsciScintilla * _edit_area;
--- a/libgui/src/main-window.cc +++ b/libgui/src/main-window.cc @@ -37,12 +37,23 @@ #include <QMessageBox> #include <QIcon> +#include "file-editor.h" #include "main-window.h" -#include "file-editor.h" +#include "octave-link.h" #include "settings-dialog.h" +#include "debug.h" +#include "defaults.h" +#include "load-save.h" +#include "toplev.h" +#include "variables.h" +#include "version.h" + +#include "cmd-hist.h" +#include "oct-env.h" + main_window::main_window (QWidget *p) - : QMainWindow (p), octave_event_observer () + : QMainWindow (p) { // We have to set up all our windows, before we finally launch octave. construct (); @@ -54,23 +65,6 @@ } void -main_window::handle_event (octave_event *e, bool accept) -{ - if (accept) - { - if (dynamic_cast<octave_clear_history_event*> (e)) - { - // After clearing the history, we need to reset the model. - _history_dock_widget->reset_model (); - } - } - else - { - // octave_event::perform failed to process event. - } -} - -void main_window::new_file () { _file_editor->request_new_file (); @@ -104,10 +98,8 @@ QFileDialog::getSaveFileName (this, tr ("Save Workspace"), resource_manager::get_home_path ()); if (!selectedFile.isEmpty ()) - { - octave_link::post_event (new octave_save_workspace_event - (*this, selectedFile.toStdString ())); - } + octave_link::post_event (this, &main_window::save_workspace_callback, + selectedFile.toStdString ()); } void @@ -117,22 +109,20 @@ QFileDialog::getOpenFileName (this, tr ("Load Workspace"), resource_manager::get_home_path ()); if (!selectedFile.isEmpty ()) - { - octave_link::post_event (new octave_load_workspace_event - (*this, selectedFile.toStdString ())); - } + octave_link::post_event (this, &main_window::load_workspace_callback, + selectedFile.toStdString ()); } void main_window::handle_clear_workspace_request () { - octave_link::post_event (new octave_clear_workspace_event (*this)); + octave_link::post_event (this, &main_window::clear_workspace_callback); } void main_window::handle_clear_history_request() { - octave_link::post_event (new octave_clear_history_event (*this)); + octave_link::post_event (this, &main_window::clear_history_callback); } void @@ -232,17 +222,15 @@ QFileDialog::getExistingDirectory(this, tr ("Set working direcotry")); if (!selectedDirectory.isEmpty ()) - { - octave_link::post_event (new octave_change_directory_event - (*this, selectedDirectory.toStdString ())); - } + octave_link::post_event (this, &main_window::change_directory_callback, + selectedDirectory.toStdString ()); } void main_window::set_current_working_directory (const QString& directory) { - octave_link::post_event (new octave_change_directory_event - (*this, directory.toStdString ())); + octave_link::post_event (this, &main_window::change_directory_callback, + directory.toStdString ()); } void @@ -360,52 +348,37 @@ void main_window::debug_continue () { - octave_link::post_event (new octave_debug_continue_event (*this)); + octave_link::post_event (this, &main_window::debug_continue_callback); } void main_window::debug_step_into () { - octave_link::post_event (new octave_debug_step_into_event (*this)); + octave_link::post_event (this, &main_window::debug_step_into_callback); } void main_window::debug_step_over () { - octave_link::post_event (new octave_debug_step_over_event (*this)); + octave_link::post_event (this, &main_window::debug_step_over_callback); } void main_window::debug_step_out () { - octave_link::post_event (new octave_debug_step_out_event (*this)); + octave_link::post_event (this, &main_window::debug_step_out_callback); } void main_window::debug_quit () { - octave_link::post_event (new octave_debug_quit_event (*this)); + octave_link::post_event (this, &main_window::debug_quit_callback); } void main_window::show_about_octave () { - QString message = - "GNU Octave\n" - "Copyright (C) 2009 John W. Eaton and others.\n" - "This is free software; see the source code for copying conditions." - "There is ABSOLUTELY NO WARRANTY; not even for MERCHANTABILITY or" - "FITNESS FOR A PARTICULAR PURPOSE. For details, type `warranty'.\n" - "\n" - "Additional information about Octave is available at http://www.octave.org.\n" - "\n" - "Please contribute if you find this software useful." - "For more information, visit http://www.octave.org/help-wanted.html\n" - "\n" - "Report bugs to <bug@octave.org> (but first, please read" - "http://www.octave.org/bugs.html to learn how to write a helpful report).\n" - "\n" - "For information about changes from previous versions, type `news'.\n"; + QString message = OCTAVE_STARTUP_MESSAGE; QMessageBox::about (this, tr ("About Octave"), message); } @@ -414,7 +387,7 @@ main_window::closeEvent (QCloseEvent *e) { e->ignore (); - octave_link::post_event (new octave_exit_event (*this)); + octave_link::post_event (this, &main_window::exit_callback); } void @@ -895,3 +868,70 @@ SLOT (handle_quit_debug_mode ())); } +void +main_window::save_workspace_callback (const std::string& file) +{ + save_workspace (file); +} + +void +main_window::load_workspace_callback (const std::string& file) +{ + load_workspace (file); +} + +void +main_window::clear_workspace_callback (void) +{ + clear_current_scope (); +} + +void +main_window::clear_history_callback (void) +{ + command_history::clear (); + + _history_dock_widget->reset_model (); +} + +void +main_window::change_directory_callback (const std::string& directory) +{ + octave_env::chdir (directory); +} + +void +main_window::debug_continue_callback (void) +{ + debug_continue (); +} + +void +main_window::debug_step_into_callback (void) +{ + debug_step ("in"); +} + +void +main_window::debug_step_over_callback (void) +{ + debug_step (); +} + +void +main_window::debug_step_out_callback (void) +{ + debug_step ("out"); +} + +void +main_window::debug_quit_callback (void) +{ + debug_quit (); +} + +void +main_window::exit_callback (void) +{ + clean_up_and_exit (0); +}
--- a/libgui/src/main-window.h +++ b/libgui/src/main-window.h @@ -44,29 +44,24 @@ // Own includes #include "resource-manager.h" -#include "octave-link.h" #include "workspace-view.h" #include "history-dockwidget.h" #include "files-dockwidget.h" #include "terminal-dockwidget.h" #include "documentation-dockwidget.h" #include "octave-qt-event-listener.h" -#include "octave-event-observer.h" /** * \class MainWindow * * Represents the main window. */ -class main_window - : public QMainWindow, public octave_event_observer +class main_window : public QMainWindow { Q_OBJECT public: main_window (QWidget * parent = 0); ~main_window (); - void handle_event (octave_event *e, bool accept); - QTerminal *get_terminal_view () { return _terminal; } history_dock_widget *get_history_dock_widget () { @@ -128,6 +123,28 @@ void construct (); void establish_octave_link (); + void save_workspace_callback (const std::string& file); + + void load_workspace_callback (const std::string& file); + + void clear_workspace_callback (void); + + void clear_history_callback (void); + + void change_directory_callback (const std::string& directory); + + void debug_continue_callback (void); + + void debug_step_into_callback (void); + + void debug_step_over_callback (void); + + void debug_step_out_callback (void); + + void debug_quit_callback (void); + + void exit_callback (void); + QTerminal * _terminal; file_editor_interface * _file_editor; QMenu * _debug_menu;
--- a/libgui/src/module.mk +++ b/libgui/src/module.mk @@ -84,8 +84,6 @@ src/m-editor/lexer-octave-gui.h \ src/main-window.h \ src/octave-adapter/octave-event-listener.h \ - src/octave-adapter/octave-event-observer.h \ - src/octave-adapter/octave-event.h \ src/octave-adapter/octave-link.h \ src/octave-adapter/octave-main-thread.h \ src/octave-gui.h \ @@ -109,7 +107,6 @@ src/m-editor/find-dialog.cc \ src/m-editor/lexer-octave-gui.cc \ src/main-window.cc \ - src/octave-adapter/octave-event.cc \ src/octave-adapter/octave-link.cc \ src/octave-adapter/octave-main-thread.cc \ src/octave-gui.cc \ @@ -144,7 +141,7 @@ -I$(top_builddir)/liboctave/operators -I$(top_srcdir)/liboctave/operators \ -I$(top_srcdir)/liboctave/system \ -I$(top_srcdir)/liboctave/util \ - -I$(top_srcdir)/libinterp \ + -I$(top_builddir)/libinterp -I$(top_srcdir)/libinterp \ -I$(top_builddir)/libinterp/parse-tree -I$(top_srcdir)/libinterp/parse-tree \ -I$(top_builddir)/libinterp/interp-core -I$(top_srcdir)/libinterp/interp-core \ -I$(top_builddir)/libinterp/interpfcn -I$(top_srcdir)/libinterp/interpfcn \
deleted file mode 100644 --- a/libgui/src/octave-adapter/octave-event-observer.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - -Copyright (C) 2011-2012 Jacob Dawid - -This file is part of Octave. - -Octave is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 3 of the License, or (at your -option) any later version. - -Octave is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with Octave; see the file COPYING. If not, see -<http://www.gnu.org/licenses/>. - -*/ - -#ifndef OCTAVEEVENTOBSERVER_H -#define OCTAVEEVENTOBSERVER_H - -class octave_event; - -/** - * \class octave_event_observer - * \brief Implements the observer part for the observer pattern. - */ -class octave_event_observer -{ - public: - octave_event_observer () { } - virtual ~octave_event_observer () { } - - /** - * This will be called after the octave_event::perform function - * has processed an event. ACCEPT will be true if the event was - * successfully handled and false otherwise. - */ - virtual void handle_event (octave_event *e, bool accept) = 0; -}; - -#include "octave-event.h" - -#endif // OCTAVEEVENTOBSERVER_H
deleted file mode 100644 --- a/libgui/src/octave-adapter/octave-event.cc +++ /dev/null @@ -1,176 +0,0 @@ -/* - -Copyright (C) 2011-2012 Jacob Dawid -Copyright (C) 2011-2012 John P. Swensen - -This file is part of Octave. - -Octave is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 3 of the License, or (at your -option) any later version. - -Octave is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with Octave; see the file COPYING. If not, see -<http://www.gnu.org/licenses/>. - -*/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string> - -#include "cmd-hist.h" -#include "oct-env.h" - -#include "debug.h" -#include "oct-obj.h" -#include "parse.h" -#include "symtab.h" -#include "toplev.h" - -#include "octave-event.h" - -#include <readline/readline.h> - -void -octave_event::call_octave_function (const std::string& name) -{ - call_octave_function (name, octave_value_list ()); -} - -void -octave_event::call_octave_function (const std::string& name, - const octave_value_list& args, - int nargout) -{ - try - { - feval (name, args, nargout); - } catch (...) { } // Ignore exceptions. Crashes without that. -} - -void -octave_event::finish_readline_event () const -{ - rl_line_buffer[0] = '\0'; - rl_point = rl_end = 0; - rl_done = 1; - //rl_forced_update_display (); -} - -bool -octave_clear_history_event::perform () -{ - int i; - while ((i = command_history::length ()) > 0) { - command_history::remove (i - 1); - } - return true; -} - -bool -octave_debug_step_into_event::perform () -{ - octave_value_list args; - args.append (octave_value ("in")); - call_octave_function ("dbstep", args); - finish_readline_event (); - return true; -} - -bool -octave_debug_step_out_event::perform () -{ - octave_value_list args; - args.append (octave_value ("out")); - call_octave_function ("dbstep", args); - finish_readline_event (); - return true; -} - - -bool -octave_exit_event::perform () -{ - clean_up_and_exit (0); - return true; -} - -bool -octave_run_file_event::perform () -{ - octave_value_list args; - args.append (octave_value (_file)); - call_octave_function ("run", args); - finish_readline_event (); - return true; -} - -bool -octave_change_directory_event::perform () -{ - return octave_env::chdir (_directory); -} - -bool -octave_load_workspace_event::perform () -{ - octave_value_list args; - args.append (octave_value (_file)); - call_octave_function ("load", args); - return true; -} - -bool -octave_save_workspace_event::perform () -{ - octave_value_list args; - args.append (octave_value (_file)); - call_octave_function ("save", args); - return true; -} - -bool -octave_add_breakpoint_event::perform () -{ - bp_table::intmap intmap; - intmap[0] = _line + 1; - - std::string previous_directory = octave_env::get_current_directory (); - octave_env::chdir (_path); - intmap = bp_table::add_breakpoint (_function_name, intmap); - octave_env::chdir (previous_directory); - return intmap.size () > 0; -} - -bool -octave_remove_breakpoint_event::perform () -{ - bp_table::intmap intmap; - intmap[0] = _line; - - std::string previous_directory = octave_env::get_current_directory (); - octave_env::chdir (_path); - bp_table::remove_breakpoint (_function_name, intmap); - octave_env::chdir (previous_directory); - return true; // TODO: Check result. -} - -bool -octave_remove_all_breakpoints_event::perform () -{ - bp_table::intmap intmap; - std::string previous_directory = octave_env::get_current_directory (); - octave_env::chdir (_path); - intmap = bp_table::remove_all_breakpoints_in_file (_function_name, true); - octave_env::chdir (previous_directory); - return intmap.size() > 0; -}
deleted file mode 100644 --- a/libgui/src/octave-adapter/octave-event.h +++ /dev/null @@ -1,379 +0,0 @@ -/* - -Copyright (C) 2011-2012 Jacob Dawid -Copyright (C) 2011-2012 John P. Swensen - -This file is part of Octave. - -Octave is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 3 of the License, or (at your -option) any later version. - -Octave is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with Octave; see the file COPYING. If not, see -<http://www.gnu.org/licenses/>. - -*/ - -#ifndef OCTAVEEVENT_H -#define OCTAVEEVENT_H - -#include <string> - -class octave_value_list; - -#include "octave-event-observer.h" - -/** - * \class octave_event - * \brief Base class for an octave event. - * In order to make communication with octave threadsafe, comunication is - * implemented via events. An application may create events and post them, - * however there is no guarantee events will be processed in a given time. - * - * In order to create an event, there must be an event observer. The event - * observer will be given the opportunity to react on the event as soon as - * it has been processed in the octave thread. Accepting and ignoring takes - * places in the octave thread. - */ -class octave_event -{ - public: - octave_event (octave_event_observer& o) - : _octave_event_observer (o) - { } - - virtual ~octave_event () - { } - - /** Performs what is necessary to make this event happen. This - * code is thread-safe since it will be executed in the octave - * thread. However, you should take care to keep this code as - * short as possible. */ - virtual bool perform () = 0; - - /** - * Pass the event on to the class that posted the event. ACCEPT - * will be true if the perform function was successful, and false - * otherwise. - */ - void handle_event (bool accept) - { - _octave_event_observer.handle_event (this, accept); - } - - protected: - void call_octave_function (const std::string& name); - - void call_octave_function (const std::string& name, - const octave_value_list& args, - int nargout = 0); - - void finish_readline_event () const; - - private: - octave_event_observer& _octave_event_observer; -}; - -class octave_update_history_event : public octave_event -{ - public: - /** Creates a new octave_exit_event. */ - octave_update_history_event (octave_event_observer& o) - : octave_event (o) - { } - - bool perform () - { return true; /* Always grant. */ } -}; - -class octave_update_workspace_event : public octave_event -{ - public: - /** Creates a new octave_exit_event. */ - octave_update_workspace_event (octave_event_observer& o) - : octave_event (o) - { } - - bool perform () - { return true; /* Always grant. */ } -}; - -/** Implements an octave exit event. */ -class octave_exit_event : public octave_event -{ - public: - /** Creates a new octave_exit_event. */ - octave_exit_event (octave_event_observer& o) - : octave_event (o) - { } - - bool perform (); -}; - -/** Implements an octave run file event. */ -class octave_run_file_event : public octave_event -{ - public: - /** Creates a new octave_run_file_event. */ - octave_run_file_event (octave_event_observer& o, - const std::string& file) - : octave_event (o) - { _file = file; } - - bool perform (); - - private: - std::string _file; -}; - -/** Implements a change directory event. */ -class octave_change_directory_event : public octave_event -{ - public: - /** Creates a new octave_change_directory_event. */ - octave_change_directory_event (octave_event_observer& o, - const std::string& directory) - : octave_event (o) - { _directory = directory; } - - bool perform (); - - private: - std::string _directory; -}; - -/** Implements a clear workspace event. */ -class octave_clear_workspace_event : public octave_event -{ - public: - /** Creates a new octave_run_file_event. */ - octave_clear_workspace_event (octave_event_observer& o) - : octave_event (o) - { } - - bool perform () - { - call_octave_function ("clear"); - return true; - } -}; - -/** Implements a load workspace event. */ -class octave_load_workspace_event : public octave_event -{ - public: - /** Creates a new octave_change_directory_event. */ - octave_load_workspace_event (octave_event_observer& o, - const std::string& file) - : octave_event (o) - { _file = file; } - - bool perform (); - - private: - std::string _file; -}; - -/** Implements a save workspace event. */ -class octave_save_workspace_event : public octave_event -{ - public: - /** Creates a new octave_change_directory_event. */ - octave_save_workspace_event (octave_event_observer& o, - const std::string& file) - : octave_event (o) - { _file = file; } - - bool perform (); - - private: - std::string _file; -}; - -class octave_clear_history_event : public octave_event -{ - public: - /** Creates a new octave_clear_history_event. */ - octave_clear_history_event (octave_event_observer& o) - : octave_event (o) - { } - - bool perform (); -}; - -class octave_add_breakpoint_event : public octave_event -{ - public: - octave_add_breakpoint_event (octave_event_observer& o, - const std::string& path, - const std::string& function_name, - int line) - : octave_event (o) - { - _path = path; - _function_name = function_name; - _line = line; - } - - bool perform (); - - std::string get_path () - { - return _path; - } - - std::string get_function_name () - { - return _function_name; - } - - int get_line () - { - return _line; - } - - private: - std::string _path; - std::string _function_name; - int _line; -}; - -class octave_remove_breakpoint_event : public octave_event -{ - public: - octave_remove_breakpoint_event (octave_event_observer& o, - const std::string& path, - const std::string& function_name, - int line) - : octave_event (o) - { - _path = path; - _function_name = function_name; - _line = line; - } - - bool perform (); - - std::string get_path () - { - return _path; - } - - std::string get_function_name () - { - return _function_name; - } - - int get_line () - { - return _line; - } - - private: - std::string _path; - std::string _function_name; - int _line; -}; - -class octave_remove_all_breakpoints_event : public octave_event -{ - public: - octave_remove_all_breakpoints_event (octave_event_observer& o, - const std::string& path, - const std::string& function_name) - : octave_event (o) - { - _path = path; - _function_name = function_name; - } - - bool perform (); - - std::string get_path () - { - return _path; - } - - std::string get_function_name () - { - return _function_name; - } - - private: - std::string _path; - std::string _function_name; -}; - -class octave_debug_step_into_event : public octave_event -{ - public: - /** Creates a new octave_debug_step_into_event. */ - octave_debug_step_into_event (octave_event_observer& o) - : octave_event (o) { } - - bool perform (); -}; - -class octave_debug_step_over_event : public octave_event -{ - public: - /** Creates a new octave_debug_step_over_event. */ - octave_debug_step_over_event (octave_event_observer& o) - : octave_event (o) { } - - bool perform () - { - call_octave_function ("dbnext"); - finish_readline_event (); - return true; - } -}; - -class octave_debug_step_out_event : public octave_event -{ - public: - /** Creates a new octave_debug_step_out_event. */ - octave_debug_step_out_event (octave_event_observer& o) - : octave_event (o) { } - - bool perform (); -}; - -class octave_debug_continue_event : public octave_event -{ - public: - /** Creates a new octave_debug_step_out_event. */ - octave_debug_continue_event (octave_event_observer& o) - : octave_event (o) { } - - bool perform () - { - call_octave_function ("dbcont"); - finish_readline_event (); - return true; - } -}; - -class octave_debug_quit_event : public octave_event -{ - public: - /** Creates a new octave_debug_step_out_event. */ - octave_debug_quit_event (octave_event_observer& o) - : octave_event (o) { } - - bool perform () - { - call_octave_function ("dbquit"); - finish_readline_event (); - return true; - } -}; - -#endif // OCTAVEEVENT_H
--- a/libgui/src/octave-adapter/octave-link.cc +++ b/libgui/src/octave-adapter/octave-link.cc @@ -55,7 +55,7 @@ octave_link::octave_link (void) : event_listener (0), event_queue_mutex (new octave_mutex ()), - event_queue (), last_cwd (), debugging (false) + gui_event_queue (), last_cwd (), debugging (false) { } void @@ -110,40 +110,17 @@ { event_queue_mutex->lock (); - while (event_queue.size () > 0) - { - octave_event *e = event_queue.front (); - - event_queue.pop (); - - bool status = e->perform (); - - e->handle_event (status); - - delete e; - } + gui_event_queue.run (); event_queue_mutex->unlock (); } void -octave_link::do_post_event (octave_event *e) -{ - if (e) - { - event_queue_mutex->lock (); - event_queue.push (e); - event_queue_mutex->unlock (); - } -} - -void octave_link::do_about_to_exit (void) { event_queue_mutex->lock (); - while (! event_queue.empty ()) - event_queue.pop (); + gui_event_queue.discard (); event_queue_mutex->unlock (); @@ -157,11 +134,6 @@ return last_cwd; } -void -octave_link::handle_event (octave_event *, bool) -{ -} - bool octave_link::instance_ok (void) {
--- a/libgui/src/octave-adapter/octave-link.h +++ b/libgui/src/octave-adapter/octave-link.h @@ -24,14 +24,13 @@ #ifndef OCTAVELINK_H #define OCTAVELINK_H -#include <queue> #include <string> class octave_mutex; +#include "event-queue.h" + #include "octave-main-thread.h" -#include "octave-event.h" -#include "octave-event-observer.h" #include "octave-event-listener.h" // \class OctaveLink @@ -42,7 +41,7 @@ // buffering access operations to octave and executing them in the // readline event hook, which lives in the octave thread. -class octave_link : public octave_event_observer +class octave_link { protected: @@ -76,10 +75,25 @@ instance->do_process_events (); } - static void post_event (octave_event *e) + template <class T> + static void post_event (T *obj, void (T::*method) (void)) { if (instance_ok ()) - instance->do_post_event (e); + instance->do_post_event (obj, method); + } + + template <class T, class A> + static void post_event (T *obj, void (T::*method) (A), A arg) + { + if (instance_ok ()) + instance->do_post_event (obj, method, arg); + } + + template <class T, class A> + static void post_event (T *obj, void (T::*method) (const A&), const A& arg) + { + if (instance_ok ()) + instance->do_post_event (obj, method, arg); } static void about_to_exit (void) @@ -128,8 +142,8 @@ // Semaphore to lock access to the event queue. octave_mutex *event_queue_mutex; - // Buffer for queueing events until they will be processed. - std::queue <octave_event *> event_queue; + // Event Queue. + event_queue gui_event_queue; // Stores the last known current working directory of octave. std::string last_cwd; @@ -141,7 +155,24 @@ void do_generate_events (void); void do_process_events (void); - void do_post_event (octave_event *e); + + template <class T> + void do_post_event (T *obj, void (T::*method) (void)) + { + gui_event_queue.add_method (obj, method); + } + + template <class T, class A> + void do_post_event (T *obj, void (T::*method) (A), A arg) + { + gui_event_queue.add_method (obj, method, arg); + } + + template <class T, class A> + void do_post_event (T *obj, void (T::*method) (const A&), const A& arg) + { + gui_event_queue.add_method (obj, method, arg); + } void do_about_to_exit (void); @@ -149,8 +180,6 @@ void do_finished_readline_hook (void) { } std::string do_last_working_directory (void); - - void handle_event (octave_event *e, bool accept); }; #endif // OCTAVELINK_H
--- a/libgui/src/workspace-model.cc +++ b/libgui/src/workspace-model.cc @@ -29,13 +29,14 @@ #include <list> -#include <symtab.h> +#include "symtab.h" +#include "variables.h" #include "workspace-model.h" #include "octave-link.h" workspace_model::workspace_model(QObject *p) - : QAbstractItemModel (p), octave_event_observer () + : QAbstractItemModel (p) { QList<QVariant> rootData; rootData << tr ("Name") << tr ("Class") << tr("Dimension") << tr ("Value"); @@ -63,68 +64,7 @@ void workspace_model::request_update_workspace () { - octave_link::post_event (new octave_update_workspace_event (*this)); -} - -void -workspace_model::handle_event (octave_event *e, bool accept) -{ - if (accept) - { - if (dynamic_cast <octave_update_workspace_event*> (e)) - { - std::list < symbol_table::symbol_record > symbolTable = symbol_table::all_variables (); - - _symbol_information.clear (); - for (std::list < symbol_table::symbol_record > ::iterator iterator = symbolTable.begin (); - iterator != symbolTable.end (); iterator++) - _symbol_information.push_back (symbol_information (*iterator)); - - beginResetModel(); - top_level_item (0)->delete_child_items (); - top_level_item (1)->delete_child_items (); - top_level_item (2)->delete_child_items (); - - foreach (const symbol_information& s, _symbol_information) - { - tree_item *child = new tree_item (); - - child->set_data (0, s.symbol ()); - child->set_data (1, s.class_name ()); - child->set_data (2, s.dimension ()); - child->set_data (3, s.value ()); - - switch (s.scope ()) - { - case symbol_information::local: - top_level_item (0)->add_child (child); - break; - - case symbol_information::global: - top_level_item (1)->add_child (child); - break; - - case symbol_information::persistent: - top_level_item (2)->add_child (child); - break; - - default: - break; - } - } - - endResetModel(); - emit model_changed(); - } - - // Post a new event in a given time. - // This prevents flooding the event queue when no events are being processed. - _update_workspace_model_timer.start (); - } - else - { - // octave_event::perform failed to process event. - } + octave_link::post_event (this, &workspace_model::update_workspace_callback); } QModelIndex @@ -236,3 +176,54 @@ return item->data(idx.column()); } +void +workspace_model::update_workspace_callback (void) +{ + std::list < symbol_table::symbol_record > symbolTable = symbol_table::all_variables (); + + _symbol_information.clear (); + for (std::list < symbol_table::symbol_record > ::iterator iterator = symbolTable.begin (); + iterator != symbolTable.end (); iterator++) + _symbol_information.push_back (symbol_information (*iterator)); + + beginResetModel(); + top_level_item (0)->delete_child_items (); + top_level_item (1)->delete_child_items (); + top_level_item (2)->delete_child_items (); + + foreach (const symbol_information& s, _symbol_information) + { + tree_item *child = new tree_item (); + + child->set_data (0, s.symbol ()); + child->set_data (1, s.class_name ()); + child->set_data (2, s.dimension ()); + child->set_data (3, s.value ()); + + switch (s.scope ()) + { + case symbol_information::local: + top_level_item (0)->add_child (child); + break; + + case symbol_information::global: + top_level_item (1)->add_child (child); + break; + + case symbol_information::persistent: + top_level_item (2)->add_child (child); + break; + + default: + break; + } + } + + endResetModel(); + emit model_changed(); + + // Post a new event in a given time. + // This prevents flooding the event queue when no events are being processed. + _update_workspace_model_timer.start (); +} +
--- a/libgui/src/workspace-model.h +++ b/libgui/src/workspace-model.h @@ -30,7 +30,6 @@ #include <QTimer> #include "symbol-information.h" -#include "octave-event-observer.h" class tree_item { @@ -112,7 +111,7 @@ }; class workspace_model - : public QAbstractItemModel, public octave_event_observer + : public QAbstractItemModel { Q_OBJECT @@ -120,8 +119,6 @@ workspace_model (QObject *parent = 0); ~workspace_model (); - void handle_event (octave_event *e, bool accept); - QVariant data (const QModelIndex &index, int role) const; Qt::ItemFlags flags (const QModelIndex &index) const; QVariant headerData (int section, Qt::Orientation orientation, @@ -142,6 +139,9 @@ void model_changed (); private: + + void update_workspace_callback (void); + /** Timer for periodically updating the workspace model from the current * symbol information. */ QTimer _update_workspace_model_timer;
--- a/libgui/src/workspace-view.h +++ b/libgui/src/workspace-view.h @@ -26,7 +26,7 @@ #include <QDockWidget> #include <QTreeView> #include <QSemaphore> -#include "octave-link.h" + #include "workspace-model.h" class workspace_view : public QDockWidget
new file mode 100644 --- /dev/null +++ b/libinterp/interp-core/action-container.h @@ -0,0 +1,342 @@ +/* + +Copyright (C) 1993-2012 John W. Eaton +Copyright (C) 2009-2010 VZLU Prague + +This file is part of Octave. + +Octave is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +Octave is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with Octave; see the file COPYING. If not, see +<http://www.gnu.org/licenses/>. + +*/ + +#if !defined (octave_action_container_h) +#define octave_action_container_h 1 + +// This class allows registering actions in a list for later +// execution, either explicitly or when the container goes out of +// scope. + +// FIXME -- is there a better name for this class? + +class +OCTINTERP_API +action_container +{ +public: + + // A generic unwind_protect element. Knows how to run itself and + // discard itself. Also, contains a pointer to the next element. + class elem + { + public: + elem (void) { } + + virtual void run (void) { } + + virtual ~elem (void) { } + + friend class action_container; + + private: + + // No copying! + + elem (const elem&); + + elem& operator = (const elem&); + }; + + // An element that merely runs a void (*)(void) function. + + class fcn_elem : public elem + { + public: + fcn_elem (void (*fptr) (void)) + : e_fptr (fptr) { } + + void run (void) { e_fptr (); } + + private: + void (*e_fptr) (void); + }; + + // An element that stores a variable of type T along with a void (*) (T) + // function pointer, and calls the function with the parameter. + + template <class T> + class fcn_arg_elem : public elem + { + public: + fcn_arg_elem (void (*fcn) (T), T arg) + : e_fcn (fcn), e_arg (arg) { } + + void run (void) { e_fcn (e_arg); } + + private: + + // No copying! + + fcn_arg_elem (const fcn_arg_elem&); + + fcn_arg_elem& operator = (const fcn_arg_elem&); + + void (*e_fcn) (T); + T e_arg; + }; + + // An element that stores a variable of type T along with a + // void (*) (const T&) function pointer, and calls the function with + // the parameter. + + template <class T> + class fcn_crefarg_elem : public elem + { + public: + fcn_crefarg_elem (void (*fcn) (const T&), const T& arg) + : e_fcn (fcn), e_arg (arg) { } + + void run (void) { e_fcn (e_arg); } + + private: + void (*e_fcn) (const T&); + T e_arg; + }; + + // An element for calling a member function. + + template <class T> + class method_elem : public elem + { + public: + method_elem (T *obj, void (T::*method) (void)) + : e_obj (obj), e_method (method) { } + + void run (void) { (e_obj->*e_method) (); } + + private: + + T *e_obj; + void (T::*e_method) (void); + + // No copying! + + method_elem (const method_elem&); + + method_elem operator = (const method_elem&); + }; + + // An element for calling a member function with a single argument + + template <class T, class A> + class method_arg_elem : public elem + { + public: + method_arg_elem (T *obj, void (T::*method) (A), A arg) + : e_obj (obj), e_method (method), e_arg (arg) { } + + void run (void) { (e_obj->*e_method) (e_arg); } + + private: + + T *e_obj; + void (T::*e_method) (A); + A e_arg; + + // No copying! + + method_arg_elem (const method_arg_elem&); + + method_arg_elem operator = (const method_arg_elem&); + }; + + // An element for calling a member function with a single argument + + template <class T, class A> + class method_crefarg_elem : public elem + { + public: + method_crefarg_elem (T *obj, void (T::*method) (const A&), const A& arg) + : e_obj (obj), e_method (method), e_arg (arg) { } + + void run (void) { (e_obj->*e_method) (e_arg); } + + private: + + T *e_obj; + void (T::*e_method) (const A&); + A e_arg; + + // No copying! + + method_crefarg_elem (const method_crefarg_elem&); + + method_crefarg_elem operator = (const method_crefarg_elem&); + }; + + // An element that stores arbitrary variable, and restores it. + + template <class T> + class restore_var_elem : public elem + { + public: + restore_var_elem (T& ref, const T& val) + : e_ptr (&ref), e_val (val) { } + + void run (void) { *e_ptr = e_val; } + + private: + + // No copying! + + restore_var_elem (const restore_var_elem&); + + restore_var_elem& operator = (const restore_var_elem&); + + T *e_ptr, e_val; + }; + + // Deletes a class allocated using new. + + template <class T> + class delete_ptr_elem : public elem + { + public: + delete_ptr_elem (T *ptr) + : e_ptr (ptr) { } + + void run (void) { delete e_ptr; } + + private: + + T *e_ptr; + + // No copying! + + delete_ptr_elem (const delete_ptr_elem&); + + delete_ptr_elem operator = (const delete_ptr_elem&); + }; + + action_container (void) { } + + virtual ~action_container (void) { } + + virtual void add (elem *new_elem) = 0; + + // Call to void func (void). + void add_fcn (void (*fcn) (void)) + { + add (new fcn_elem (fcn)); + } + + // Call to void func (T). + template <class T> + void add_fcn (void (*action) (T), T val) + { + add (new fcn_arg_elem<T> (action, val)); + } + + // Call to void func (const T&). + template <class T> + void add_fcn (void (*action) (const T&), const T& val) + { + add (new fcn_crefarg_elem<T> (action, val)); + } + + // Call to T::method (void). + template <class T> + void add_method (T *obj, void (T::*method) (void)) + { + add (new method_elem<T> (obj, method)); + } + + // Call to T::method (A). + template <class T, class A> + void add_method (T *obj, void (T::*method) (A), A arg) + { + add (new method_arg_elem<T, A> (obj, method, arg)); + } + + // Call to T::method (const A&). + template <class T, class A> + void add_method (T *obj, void (T::*method) (const A&), const A& arg) + { + add (new method_crefarg_elem<T, A> (obj, method, arg)); + } + + // Call to delete (T*). + + template <class T> + void add_delete (T *obj) + { + add (new delete_ptr_elem<T> (obj)); + } + + // Protect any variable. + template <class T> + void protect_var (T& var) + { + add (new restore_var_elem<T> (var, var)); + } + + // Protect any variable, value given. + template <class T> + void protect_var (T& var, const T& val) + { + add (new restore_var_elem<T> (var, val)); + } + + operator bool (void) const { return ! empty (); } + + virtual void run_first (void) = 0; + + void run (size_t num) + { + if (num > size ()) + num = size (); + + for (size_t i = 0; i < num; i++) + run_first (); + } + + void run (void) { run (size ()); } + + virtual void discard_first (void) = 0; + + void discard (size_t num) + { + if (num > size ()) + num = size (); + + for (size_t i = 0; i < num; i++) + discard_first (); + } + + void discard (void) { discard (size ()); } + + virtual size_t size (void) const = 0; + + bool empty (void) const { return size () == 0; } + +private: + + // No copying! + + action_container (const action_container&); + + action_container& operator = (const action_container&); +}; + +#endif
--- a/libinterp/interp-core/defun-dld.h +++ b/libinterp/interp-core/defun-dld.h @@ -57,14 +57,14 @@ #else #define DEFUN_DLD(name, args_name, nargout_name, doc) \ - DECLARE_FUN (name, args_name, nargout_name); \ + DECLARE_FUN_NO_DEFAULTS (name, args_name, nargout_name); \ DEFINE_FUN_INSTALLER_FUN (name, doc) \ - DECLARE_FUN (name, args_name, nargout_name) + DECLARE_FUN_NO_DEFAULTS (name, args_name, nargout_name) #define DEFUNX_DLD(name, fname, gname, args_name, nargout_name, doc) \ - DECLARE_FUNX (fname, args_name, nargout_name); \ + DECLARE_FUNX_NO_DEFAULTS (fname, args_name, nargout_name); \ DEFINE_FUNX_INSTALLER_FUN (name, fname, gname, doc) \ - DECLARE_FUNX (fname, args_name, nargout_name) + DECLARE_FUNX_NO_DEFAULTS (fname, args_name, nargout_name) #endif
--- a/libinterp/interp-core/defun-int.h +++ b/libinterp/interp-core/defun-int.h @@ -77,13 +77,23 @@ extern OCTINTERP_API void defun_isargout (int, int, bool *); +#define DECLARE_FUNXX(name, args_decl, nargout_decl) \ + OCTAVE_EXPORT octave_value_list name (args_decl, nargout_decl) + #define DECLARE_FUNX(name, args_name, nargout_name) \ - OCTAVE_EXPORT octave_value_list \ - name (const octave_value_list& args_name, int nargout_name) + DECLARE_FUNXX (name, \ + const octave_value_list& args_name = octave_value_list (), \ + int nargout_name = 0) + +#define DECLARE_FUNX_NO_DEFAULTS(name, args_name, nargout_name) \ + DECLARE_FUNXX (name, const octave_value_list& args_name, int nargout_name) #define DECLARE_FUN(name, args_name, nargout_name) \ DECLARE_FUNX (F ## name, args_name, nargout_name) +#define DECLARE_FUN_NO_DEFAULTS(name, args_name, nargout_name) \ + DECLARE_FUNX_NO_DEFAULTS (F ## name, args_name, nargout_name) + // Define the code that will be used to insert the new function into // the symbol table. We look for this name instead of the actual // function so that we can easily install the doc std::string too.
new file mode 100644 --- /dev/null +++ b/libinterp/interp-core/event-queue.h @@ -0,0 +1,126 @@ +/* + +Copyright (C) 2012 John W. Eaton + +This file is part of Octave. + +Octave is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +Octave is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with Octave; see the file COPYING. If not, see +<http://www.gnu.org/licenses/>. + +*/ + +#if !defined (octave_event_queue_h) +#define octave_event_queue_h 1 + +#include <queue> +#include <memory> + +#include "action-container.h" + +class +OCTINTERP_API +event_queue : public action_container +{ +public: + + event_queue (void) : fifo () { } + + // Destructor should not raise an exception, so all actions + // registered should be exception-safe (but setting error_state is + // allowed). If you're not sure, see event_queue_safe. + + ~event_queue (void) { run (); } + + void add (elem *new_elem) + { + fifo.push (new_elem); + } + + void run_first (void) + { + if (! empty ()) + { + // No leak on exception! + std::auto_ptr<elem> ptr (fifo.front ()); + fifo.pop (); + ptr->run (); + } + } + + void discard_first (void) + { + if (! empty ()) + { + elem *ptr = fifo.front (); + fifo.pop (); + delete ptr; + } + } + + size_t size (void) const { return fifo.size (); } + +protected: + + std::queue<elem *> fifo; + +private: + + // No copying! + + event_queue (const event_queue&); + + event_queue& operator = (const event_queue&); +}; + +// Like event_queue, but this one will guard against the +// possibility of seeing an exception (or interrupt) in the cleanup +// actions. Not that we can do much about it, but at least we won't +// crash. + +class +event_queue_safe : public event_queue +{ +private: + + static void gripe_exception (void); + +public: + + event_queue_safe (void) : event_queue () { } + + ~event_queue_safe (void) + { + while (! empty ()) + { + try + { + run_first (); + } + catch (...) // Yes, the black hole. Remember we're in a dtor. + { + gripe_exception (); + } + } + } + +private: + + // No copying! + + event_queue_safe (const event_queue_safe&); + + event_queue_safe& operator = (const event_queue_safe&); +}; + +#endif
--- a/libinterp/interp-core/module.mk +++ b/libinterp/interp-core/module.mk @@ -12,6 +12,7 @@ INTERP_CORE_INC = \ interp-core/Cell.h \ + interp-core/action-container.h \ interp-core/c-file-ptr-stream.h \ interp-core/comment-list.h \ interp-core/cutils.h \ @@ -19,6 +20,7 @@ interp-core/defun-int.h \ interp-core/display.h \ interp-core/dynamic-ld.h \ + interp-core/event-queue.h \ interp-core/gl-render.h \ interp-core/gl2ps-renderer.h \ interp-core/gl2ps.h \
--- a/libinterp/interp-core/unwind-prot.cc +++ b/libinterp/interp-core/unwind-prot.cc @@ -25,12 +25,8 @@ #include <config.h> #endif -#include <cstddef> -#include <cstring> - #include "error.h" #include "unwind-prot.h" -#include "utils.h" void unwind_protect_safe::gripe_exception (void) {
--- a/libinterp/interp-core/unwind-prot.h +++ b/libinterp/interp-core/unwind-prot.h @@ -24,289 +24,74 @@ #if !defined (octave_unwind_prot_h) #define octave_unwind_prot_h 1 -#include <cstddef> - -#include <string> +#include <stack> #include <memory> -// This class allows registering cleanup actions. +#include "action-container.h" + class OCTINTERP_API -unwind_protect +unwind_protect : public action_container { public: - // A generic unwind_protect element. Knows how to run itself and discard itself. - // Also, contains a pointer to the next element. - class elem - { - elem *next; - - public: - elem (void) : next (0) { } - - virtual void run (void) { } - - virtual ~elem (void) { } - - friend class unwind_protect; - - private: - - // No copying! - - elem (const elem&); - - elem& operator = (const elem&); - }; - - // An element that merely runs a void (*)(void) function. - - class fcn_elem : public elem - { - public: - fcn_elem (void (*fptr) (void)) - : e_fptr (fptr) { } + unwind_protect (void) : lifo () { } - void run (void) { e_fptr (); } - - private: - void (*e_fptr) (void); - }; - - // An element that stores a variable of type T along with a void (*) (T) - // function pointer, and calls the function with the parameter. - - template <class T> - class fcn_arg_elem : public elem - { - public: - fcn_arg_elem (void (*fcn) (T), T arg) - : e_fcn (fcn), e_arg (arg) { } + // Destructor should not raise an exception, so all actions + // registered should be exception-safe (but setting error_state is + // allowed). If you're not sure, see unwind_protect_safe. - void run (void) { e_fcn (e_arg); } - - private: - - // No copying! - - fcn_arg_elem (const fcn_arg_elem&); - - fcn_arg_elem& operator = (const fcn_arg_elem&); - - void (*e_fcn) (T); - T e_arg; - }; - - // An element that stores a variable of type T along with a void (*) (const T&) - // function pointer, and calls the function with the parameter. + ~unwind_protect (void) { run (); } - template <class T> - class fcn_crefarg_elem : public elem + virtual void add (elem *new_elem) { - public: - fcn_crefarg_elem (void (*fcn) (const T&), T arg) - : e_fcn (fcn), e_arg (arg) { } - - void run (void) { e_fcn (e_arg); } - - private: - void (*e_fcn) (const T&); - T e_arg; - }; - - // An element for calling a member function. - - template <class T> - class method_elem : public elem - { - public: - method_elem (T *obj, void (T::*method) (void)) - : e_obj (obj), e_method (method) { } - - void run (void) { (e_obj->*e_method) (); } - - private: - - T *e_obj; - void (T::*e_method) (void); - - // No copying! - - method_elem (const method_elem&); + lifo.push (new_elem); + } - method_elem operator = (const method_elem&); - }; - - // An element that stores arbitrary variable, and restores it. - - template <class T> - class restore_var_elem : public elem + void add (void (*fcn) (void *), void *ptr = 0) GCC_ATTR_DEPRECATED { - public: - restore_var_elem (T& ref, const T& val) - : e_ptr (&ref), e_val (val) { } - - void run (void) { *e_ptr = e_val; } - - private: + add (new fcn_arg_elem<void *> (fcn, ptr)); + } - // No copying! - - restore_var_elem (const restore_var_elem&); - - restore_var_elem& operator = (const restore_var_elem&); - - T *e_ptr, e_val; - }; + operator bool (void) const { return ! empty (); } - // Deletes a class allocated using new. - - template <class T> - class delete_ptr_elem : public elem - { - public: - delete_ptr_elem (T *ptr) - : e_ptr (ptr) { } + void run_top (void) GCC_ATTR_DEPRECATED { run_first (); } - void run (void) { delete e_ptr; } - - private: - - T *e_ptr; - - // No copying! - - delete_ptr_elem (const delete_ptr_elem&); - - delete_ptr_elem operator = (const delete_ptr_elem&); - }; - - unwind_protect (void) : head () { } - - void add (elem *new_elem) - { - new_elem->next = head; - head = new_elem; - } - - // For backward compatibility. - void add (void (*fcn) (void *), void *ptr = 0) - { - add (new fcn_arg_elem<void *> (fcn, ptr)); - } + void run_first (void) + { + if (! empty ()) + { + // No leak on exception! + std::auto_ptr<elem> ptr (lifo.top ()); + lifo.pop (); + ptr->run (); + } + } - // Call to void func (void). - void add_fcn (void (*fcn) (void)) - { - add (new fcn_elem (fcn)); - } - - // Call to void func (T). - template <class T> - void add_fcn (void (*action) (T), T val) - { - add (new fcn_arg_elem<T> (action, val)); - } + void run_top (int num) GCC_ATTR_DEPRECATED { run (num); } - // Call to void func (const T&). - template <class T> - void add_fcn (void (*action) (const T&), T val) - { - add (new fcn_crefarg_elem<T> (action, val)); - } - - // Call to T::method (void). - template <class T> - void add_method (T *obj, void (T::*method) (void)) - { - add (new method_elem<T> (obj, method)); - } - - // Call to delete (T*). - - template <class T> - void add_delete (T *obj) - { - add (new delete_ptr_elem<T> (obj)); - } + void discard_top (void) GCC_ATTR_DEPRECATED { discard_first (); } - // Protect any variable. - template <class T> - void protect_var (T& var) - { - add (new restore_var_elem<T> (var, var)); - } - - // Protect any variable, value given. - template <class T> - void protect_var (T& var, const T& val) - { - add (new restore_var_elem<T> (var, val)); - } - - operator bool (void) const - { - return head != 0; - } - - void run_top (void) - { - if (head) - { - // No leak on exception! - std::auto_ptr<elem> ptr (head); - head = ptr->next; - ptr->run (); - } - } - - void run_top (int num) - { - while (num-- > 0) - run_top (); - } + void discard_first (void) + { + if (! empty ()) + { + elem *ptr = lifo.top (); + lifo.pop (); + delete ptr; + } + } - void discard_top (void) - { - if (head) - { - elem *ptr = head; - head = ptr->next; - delete ptr; - } - } + void discard_top (int num) GCC_ATTR_DEPRECATED { discard (num); } - void discard_top (int num) - { - while (num-- > 0) - discard_top (); - } + size_t size (void) const { return lifo.size (); } - void run (void) - { - while (head) - run_top (); - } +protected: - void discard (void) - { - while (head) - discard_top (); - } - - // Destructor should not raise an exception, so all actions registered should - // be exception-safe (but setting error_state is allowed). If you're not sure, - // see unwind_protect_safe. - ~unwind_protect (void) - { - run (); - } + std::stack<elem *> lifo; private: - elem *head; - // No copying! unwind_protect (const unwind_protect&); @@ -314,24 +99,30 @@ unwind_protect& operator = (const unwind_protect&); }; -// Like unwind_protect, but this one will guard against the possibility of seeing -// an exception (or interrupt) in the cleanup actions. Not that we can do much about -// it, but at least we won't crash. +// Like unwind_protect, but this one will guard against the +// possibility of seeing an exception (or interrupt) in the cleanup +// actions. Not that we can do much about it, but at least we won't +// crash. class OCTINTERP_API unwind_protect_safe : public unwind_protect { +private: + static void gripe_exception (void); public: + + unwind_protect_safe (void) : unwind_protect () { } + ~unwind_protect_safe (void) { - while (*this) + while (! empty ()) { try { - run_top (); + run_first (); } catch (...) // Yes, the black hole. Remember we're in a dtor. { @@ -339,6 +130,14 @@ } } } + +private: + + // No copying! + + unwind_protect_safe (const unwind_protect_safe&); + + unwind_protect_safe& operator = (const unwind_protect_safe&); }; #endif
--- a/libinterp/interpfcn/debug.cc +++ b/libinterp/interpfcn/debug.cc @@ -1201,6 +1201,17 @@ DEFALIAS (dbnext, dbstep); +void +debug_step (const std::string& what) +{ + octave_value_list args; + + if (! what.empty ()) + args(0) = what; + + Fdbstep (args); +} + DEFUN (dbcont, args, , "-*- texinfo -*-\n\ @deftypefn {Command} {} dbcont\n\ @@ -1225,6 +1236,12 @@ return octave_value_list (); } +void +debug_continue (void) +{ + Fdbcont (); +} + DEFUN (dbquit, args, , "-*- texinfo -*-\n\ @deftypefn {Command} {} dbquit\n\ @@ -1252,6 +1269,12 @@ return octave_value_list (); } +void +debug_quit (void) +{ + Fdbquit (); +} + DEFUN (isdebugmode, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} isdebugmode ()\n\
--- a/libinterp/interpfcn/debug.h +++ b/libinterp/interpfcn/debug.h @@ -129,6 +129,12 @@ bool do_have_breakpoints (void) { return (! bp_set.empty ()); } }; -std::string get_file_line (const std::string& fname, size_t line); +extern std::string get_file_line (const std::string& fname, size_t line); + +extern void OCTINTERP_API debug_continue (void); + +extern void OCTINTERP_API debug_step (const std::string& what = std::string ()); + +extern void OCTINTERP_API debug_quit (void); #endif
--- a/libinterp/interpfcn/load-save.cc +++ b/libinterp/interpfcn/load-save.cc @@ -1443,6 +1443,16 @@ } } +void +load_workspace (const std::string& file) +{ + octave_value_list args; + + if (! file.empty ()) + args(0) = file; + + Fload (args); +} DEFUN (save, args, , "-*- texinfo -*-\n\ @@ -1745,6 +1755,17 @@ return retval; } +void +save_workspace (const std::string& file) +{ + octave_value_list args; + + if (! file.empty ()) + args(0) = file; + + Fsave (args); +} + DEFUN (crash_dumps_octave_core, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {@var{val} =} crash_dumps_octave_core ()\n\
--- a/libinterp/interpfcn/load-save.h +++ b/libinterp/interpfcn/load-save.h @@ -87,4 +87,7 @@ extern void write_header (std::ostream& os, load_save_format format); +extern OCTINTERP_API void load_workspace (const std::string& file); +extern OCTINTERP_API void save_workspace (const std::string& file); + #endif
--- a/libinterp/interpfcn/variables.cc +++ b/libinterp/interpfcn/variables.cc @@ -2340,8 +2340,8 @@ { if (argc == 1) { - do_clear_globals (argv, argc, 1); - do_clear_variables (argv, argc, 1); + do_clear_globals (argv, argc, true); + do_clear_variables (argv, argc, true); } else { @@ -2460,6 +2460,12 @@ return retval; } +void +clear_current_scope (void) +{ + Fclear (); +} + DEFUN (whos_line_format, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {@var{val} =} whos_line_format ()\n\
--- a/libinterp/interpfcn/variables.h +++ b/libinterp/interpfcn/variables.h @@ -148,4 +148,7 @@ extern OCTINTERP_API void maybe_missing_function_hook (const std::string& name); +// Equivalent to Fclear without any arguments. +extern OCTINTERP_API void clear_current_scope (void); + #endif
--- a/liboctave/util/cmd-hist.cc +++ b/liboctave/util/cmd-hist.cc @@ -69,6 +69,8 @@ void do_remove (int); + void do_clear (void); + int do_where (void) const; int do_length (void) const; @@ -201,6 +203,12 @@ ::octave_remove_history (n); } +void +gnu_history::do_clear (void) +{ + ::octave_clear_history (); +} + int gnu_history::do_where (void) const { @@ -587,6 +595,13 @@ instance->do_remove (n); } +void +command_history::clear (void) +{ + if (instance_ok ()) + instance->do_clear (); +} + int command_history::where (void) { @@ -807,6 +822,11 @@ { } +void +command_history::do_clear (void) +{ +} + int command_history::do_where (void) const {
--- a/liboctave/util/cmd-hist.h +++ b/liboctave/util/cmd-hist.h @@ -65,6 +65,8 @@ static void remove (int); + static void clear (void); + static int where (void); static int length (void); @@ -158,6 +160,8 @@ virtual void do_remove (int); + virtual void do_clear (void); + virtual int do_where (void) const; virtual int do_length (void) const;