# HG changeset patch # User John W. Eaton # Date 1468149321 14400 # Node ID c2c668b3051be4158c72fe0246335bbe7241502d # Parent c3823cb0ea02eb0cd497df11f778dcc38c791fd9 use classes for octave application and interpreter * main-cli.cc (main): Simplify using class objects. * main-gui.cc (main): Likeiwse. * octave.h, octave.cc (octave::cmdline_options, octave::application, octave::cli_application, octave::embedded_application, octave::interpreter): New classes. Replace ordinary functions and static/global data with objects. Access global application data through application object. * octave-gui.h, octave-gui.cc (octave::gui_application): New class. Replace ordinary functions and static/global data with objects. * main-window.cc (main_window::m_app_context): New data member. (main_window::main_window): Pass application object instead of start_gui flag. (main_window::construct_octave_qt_link): Pass m_app_context to octave_qt_link constructor. * octave-interpreter.h, octave-interpreter.cc (octave_interpreter::m_app_context, octave_interpreter::m_exit_status): New data members. (octave_interpreter::execute): Use class object to start interpreter. Save exit status. * octave-qt-link.h, octave-qt-link.cc (octave_qt_link::m_app_context): New data member. (octave_qt_link::do_set_default_prompts): Make prompt settings conditional on whether the GUI is running. * input.h, input.cc (interactive, forced_interactive): Delete global data. * dirfns.cc, error.cc, input.cc, oct-stream.cc, pager.cc, sighandlers.cc, sysdep.cc, toplev.cc, lex.ll: Access interactive and forced_interactive through global application object. diff -r c3823cb0ea02 -r c2c668b3051b libgui/src/main-window.cc --- a/libgui/src/main-window.cc Mon Jul 11 13:45:12 2016 -0400 +++ b/libgui/src/main-window.cc Sun Jul 10 07:15:21 2016 -0400 @@ -60,6 +60,7 @@ #include "builtin-defun-decls.h" #include "defaults.h" +#include "octave.h" #include "symtab.h" #include "version.h" #include "utils.h" @@ -74,26 +75,29 @@ #endif } -main_window::main_window (QWidget *p, bool start_gui) - : QMainWindow (p), - _workspace_model (start_gui ? new workspace_model () : 0), - status_bar (start_gui ? new QStatusBar () : 0), - command_window (start_gui ? new terminal_dock_widget (this) : 0), - history_window (start_gui ? new history_dock_widget (this) : 0), - file_browser_window (start_gui ? new files_dock_widget (this) : 0), - doc_browser_window (start_gui ? new documentation_dock_widget (this) : 0), - editor_window (start_gui ? create_default_editor (this) : 0), - workspace_window (start_gui ? new workspace_view (this) : 0), - _settings_dlg (0), - find_files_dlg (0), - release_notes_window (0), - community_news_window (0), - _octave_qt_link (0), +main_window::main_window (QWidget *p, octave::gui_application *app_context) + : QMainWindow (p), m_app_context (app_context), _workspace_model (0), + status_bar (0), command_window (0), history_window (0), + file_browser_window (0), doc_browser_window (0), editor_window (0), + workspace_window (0), _settings_dlg (0), find_files_dlg (0), + release_notes_window (0), community_news_window (0), _octave_qt_link (0), _clipboard (QApplication::clipboard ()), _prevent_readline_conflicts (true), _suppress_dbg_location (true), - _start_gui (start_gui) + _start_gui (app_context && app_context->start_gui_p ()) { + if (_start_gui) + { + _workspace_model = new workspace_model (); + status_bar = new QStatusBar (); + command_window = new terminal_dock_widget (this); + history_window = new history_dock_widget (this); + file_browser_window = new files_dock_widget (this); + doc_browser_window = new documentation_dock_widget (this); + editor_window = create_default_editor (this); + workspace_window = new workspace_view (this); + } + QSettings *settings = resource_manager::get_settings (); bool connect_to_web = true; @@ -115,7 +119,7 @@ QDateTime current = QDateTime::currentDateTime (); QDateTime one_day_ago = current.addDays (-1); - if (start_gui && connect_to_web + if (_start_gui && connect_to_web && (! last_checked.isValid () || one_day_ago > last_checked)) load_and_display_community_news (serial); @@ -1479,7 +1483,7 @@ void main_window::construct_octave_qt_link (void) { - _octave_qt_link = new octave_qt_link (this); + _octave_qt_link = new octave_qt_link (this, m_app_context); connect (_octave_qt_link, SIGNAL (exit_app_signal (int)), this, SLOT (exit_app (int))); diff -r c3823cb0ea02 -r c2c668b3051b libgui/src/main-window.h --- a/libgui/src/main-window.h Mon Jul 11 13:45:12 2016 -0400 +++ b/libgui/src/main-window.h Sun Jul 10 07:15:21 2016 -0400 @@ -46,17 +46,18 @@ // Own includes #include "dialog.h" +#include "documentation-dock-widget.h" +#include "files-dock-widget.h" +#include "find-files-dialog.h" +#include "history-dock-widget.h" +#include "octave-cmd.h" +#include "octave-dock-widget.h" +#include "octave-gui.h" +#include "octave-qt-link.h" #include "resource-manager.h" +#include "terminal-dock-widget.h" #include "workspace-model.h" #include "workspace-view.h" -#include "history-dock-widget.h" -#include "files-dock-widget.h" -#include "terminal-dock-widget.h" -#include "documentation-dock-widget.h" -#include "octave-qt-link.h" -#include "octave-dock-widget.h" -#include "find-files-dialog.h" -#include "octave-cmd.h" class settings_dialog; @@ -74,7 +75,7 @@ typedef std::pair name_pair; typedef std::pair int_pair; - main_window (QWidget *parent = 0, bool start_gui = true); + main_window (QWidget *parent, octave::gui_application *app_context); ~main_window (void); @@ -291,6 +292,8 @@ void configure_shortcuts (); + octave::gui_application *m_app_context; + workspace_model *_workspace_model; QHash _hash_menu_text; diff -r c3823cb0ea02 -r c2c668b3051b libgui/src/octave-gui.cc --- a/libgui/src/octave-gui.cc Mon Jul 11 13:45:12 2016 -0400 +++ b/libgui/src/octave-gui.cc Sun Jul 10 07:15:21 2016 -0400 @@ -29,6 +29,8 @@ #include #include +#include + #include #if defined (HAVE_SYS_IOCTL_H) @@ -40,10 +42,12 @@ #include "oct-syscalls.h" #include "builtin-defun-decls.h" +#include "display.h" #if defined (HAVE_QT_GRAPHICS) # include "__init_qt__.h" #endif #include "octave.h" +#include "unistd-wrappers.h" #include "main-window.h" #include "octave-gui.h" @@ -59,101 +63,164 @@ { } -// If START_GUI is false, we still set up the QApplication so that we -// can use Qt widgets for plot windows. - -int -octave_start_gui (int argc, char *argv[], bool start_gui) +namespace octave { - octave_thread_manager::block_interrupt_signal (); + bool gui_application::start_gui_p (void) const + { + if (m_options.no_window_system ()) + return false; + + std::string err_msg; + if (! display_info::display_available (err_msg)) + { + if (! (m_options.inhibit_startup_message () || err_msg.empty ())) + warning (err_msg.c_str ()); + + return false; + } - std::string show_gui_msgs = octave::sys::env::getenv ("OCTAVE_SHOW_GUI_MESSAGES"); + if (! m_options.line_editing ()) + { + if (! (m_options.inhibit_startup_message () + || m_options.no_gui ())) + warning ("--no-line-editing option given, disabling GUI"); + + return false; + } + + if (m_options.force_gui ()) + return true; + + if (m_options.no_gui ()) + return false; - // Installing our handler suppresses the messages. - if (show_gui_msgs.empty ()) - qInstallMsgHandler (message_handler); + if (m_options.persist ()) + return true; + + // If stdin is not a tty, then assume we are reading commands from a + // pipe or a redirected file and the GUI should not start. If this + // is not the case (for example, starting from a desktop "launcher" + // with no terminal) and you want to start the GUI, you may use the + // --force-gui option to start the GUI. + + if (! octave_isatty_wrapper (fileno (stdin))) + return false; + + // If we have code to eval or execute from a file, and we are going + // to exit immediately after executing it, don't start the gui. + + std::string code_to_eval = m_options.code_to_eval (); + if (! code_to_eval.empty () || m_have_script_file) + return false; + + return true; + } + + int gui_application::execute (void) + { + octave_thread_manager::block_interrupt_signal (); + + std::string show_gui_msgs = octave::sys::env::getenv ("OCTAVE_SHOW_GUI_MESSAGES"); + + // Installing our handler suppresses the messages. + + if (show_gui_msgs.empty ()) + qInstallMsgHandler (message_handler); #if defined (HAVE_QT_GRAPHICS) - install___init_qt___functions (); + install___init_qt___functions (); - Fregister_graphics_toolkit (ovl ("qt")); + Fregister_graphics_toolkit (ovl ("qt")); #endif - QApplication application (argc, argv); - QTranslator gui_tr, qt_tr, qsci_tr; + // If START_GUI is false, we still set up the QApplication so that + // we can use Qt widgets for plot windows. - // Set the codec for all strings (before wizard) + QApplication qt_app (m_argc, m_argv); + QTranslator gui_tr, qt_tr, qsci_tr; + + // Set the codec for all strings (before wizard or any GUI object) #if ! defined (Q_OS_WIN32) - QTextCodec::setCodecForCStrings (QTextCodec::codecForName ("UTF-8")); + QTextCodec::setCodecForCStrings (QTextCodec::codecForName ("UTF-8")); #endif - // show wizard if this is the first run - if (resource_manager::is_first_run () && start_gui) - { - // before wizard - resource_manager::config_translators (&qt_tr, &qsci_tr, &gui_tr); - application.installTranslator (&qt_tr); - application.installTranslator (&gui_tr); - application.installTranslator (&qsci_tr); + bool start_gui = start_gui_p (); + + // Show welcome wizard if this is the first run. + + if (resource_manager::is_first_run () && start_gui) + { + // Before wizard. + resource_manager::config_translators (&qt_tr, &qsci_tr, &gui_tr); - welcome_wizard welcomeWizard; - - if (welcomeWizard.exec () == QDialog::Rejected) - exit (1); + qt_app.installTranslator (&qt_tr); + qt_app.installTranslator (&gui_tr); + qt_app.installTranslator (&qsci_tr); - resource_manager::reload_settings (); // install settings file - } - else - { - resource_manager::reload_settings (); // get settings file + welcome_wizard welcomeWizard; + + if (welcomeWizard.exec () == QDialog::Rejected) + exit (1); - // after settings - resource_manager::config_translators (&qt_tr, &qsci_tr, &gui_tr); - application.installTranslator (&qt_tr); - application.installTranslator (&gui_tr); - if (start_gui) - application.installTranslator (&qsci_tr); - } + // Install settings file. + resource_manager::reload_settings (); + } + else + { + // Get settings file. + resource_manager::reload_settings (); + + // After settings. + resource_manager::config_translators (&qt_tr, &qsci_tr, &gui_tr); + + qt_app.installTranslator (&qt_tr); + qt_app.installTranslator (&gui_tr); - if (start_gui) - { - // update network-settings - resource_manager::update_network_settings (); + if (start_gui) + qt_app.installTranslator (&qsci_tr); + } + + if (start_gui) + { + resource_manager::update_network_settings (); - // We provide specific terminal capabilities, so ensure that TERM is - // always set appropriately + // We provide specific terminal capabilities, so ensure that + // TERM is always set appropriately. + #if defined (OCTAVE_USE_WINDOWS_API) - octave::sys::env::putenv ("TERM", "cygwin"); + octave::sys::env::putenv ("TERM", "cygwin"); #else - octave::sys::env::putenv ("TERM", "xterm"); + octave::sys::env::putenv ("TERM", "xterm"); #endif - // shortcut manager - shortcut_manager::init_data (); - } + shortcut_manager::init_data (); + } - // Force left-to-right alignment (see bug #46204) - application.setLayoutDirection (Qt::LeftToRight); + // Force left-to-right alignment (see bug #46204) + qt_app.setLayoutDirection (Qt::LeftToRight); + + // Create and show main window. - // Create and show main window. - - main_window w (0, start_gui); + main_window w (0, this); - if (start_gui) - { - w.read_settings (); + if (start_gui) + { + w.read_settings (); + + w.init_terminal_size (); - w.init_terminal_size (); + // Connect signals for changes in visibility not before w + // is shown. - // Connect signals for changes in visibility not before w - // is shown. + w.connect_visibility_changed (); - w.connect_visibility_changed (); + w.focus_command_window (); - w.focus_command_window (); - } - else - application.setQuitOnLastWindowClosed (false); + gui_running (true); + } + else + qt_app.setQuitOnLastWindowClosed (false); - return application.exec (); + return qt_app.exec (); + } } diff -r c3823cb0ea02 -r c2c668b3051b libgui/src/octave-gui.h --- a/libgui/src/octave-gui.h Mon Jul 11 13:45:12 2016 -0400 +++ b/libgui/src/octave-gui.h Sun Jul 10 07:15:21 2016 -0400 @@ -23,7 +23,39 @@ #if ! defined (octave_octave_gui_h) #define octave_octave_gui_h 1 -extern OCTGUI_API int octave_start_gui (int argc, char **argv, - bool start_gui = true); +#include "octave.h" + +namespace octave +{ + class OCTGUI_API gui_application : public application + { + public: + + gui_application (int argc, char **argv) + : application (argc, argv), m_argc (argc), m_argv (argv), + m_gui_running (false) + { } + + // Should we start the GUI or fall back to the CLI? + bool start_gui_p (void) const; + + int execute (void); + + bool gui_running (void) const { return m_gui_running; } + void gui_running (bool arg) { m_gui_running = arg; } + + private: + + // No copying, at least not yet. + + gui_application (const gui_application&); + + gui_application& operator = (const gui_application&); + + int m_argc; + char **m_argv; + bool m_gui_running; + }; +} #endif diff -r c3823cb0ea02 -r c2c668b3051b libgui/src/octave-interpreter.cc --- a/libgui/src/octave-interpreter.cc Mon Jul 11 13:45:12 2016 -0400 +++ b/libgui/src/octave-interpreter.cc Sun Jul 10 07:15:21 2016 -0400 @@ -29,6 +29,11 @@ #include "octave-interpreter.h" +octave_interpreter::octave_interpreter (octave::application *app_context) + : QObject (), thread_manager (), m_app_context (app_context), + m_exit_status (0) +{ } + void octave_interpreter::execute (void) { @@ -36,12 +41,13 @@ octave_thread_manager::unblock_interrupt_signal (); - octave_initialize_interpreter (octave_cmdline_argc, octave_cmdline_argv, - octave_embedded); + // The application context owns the interpreter. + + m_app_context->create_interpreter (); emit octave_ready_signal (); - octave_execute_interpreter (); + m_exit_status = m_app_context->execute_interpreter (); } void diff -r c3823cb0ea02 -r c2c668b3051b libgui/src/octave-interpreter.h --- a/libgui/src/octave-interpreter.h Mon Jul 11 13:45:12 2016 -0400 +++ b/libgui/src/octave-interpreter.h Sun Jul 10 07:15:21 2016 -0400 @@ -26,6 +26,8 @@ #include +#include "octave.h" + #include "thread-manager.h" class octave_interpreter : public QObject @@ -36,7 +38,9 @@ // An object to manage the Octave interpreter. - octave_interpreter (void) : QObject (), thread_manager () { } + octave_interpreter (octave::application *app_context); + + ~octave_interpreter (void) { } signals: @@ -53,6 +57,10 @@ private: octave_thread_manager thread_manager; + + octave::application *m_app_context; + + int m_exit_status; }; #endif diff -r c3823cb0ea02 -r c2c668b3051b libgui/src/octave-qt-link.cc --- a/libgui/src/octave-qt-link.cc Mon Jul 11 13:45:12 2016 -0400 +++ b/libgui/src/octave-qt-link.cc Sun Jul 10 07:15:21 2016 -0400 @@ -31,22 +31,25 @@ #include #include +#include "oct-env.h" #include "str-vec.h" + +#include "builtin-defun-decls.h" #include "dialog.h" #include "error.h" -#include "workspace-element.h" -#include "builtin-defun-decls.h" #include "load-path.h" -#include "oct-env.h" #include "utils.h" +#include "octave-gui.h" #include "octave-qt-link.h" - #include "resource-manager.h" +#include "workspace-element.h" -octave_qt_link::octave_qt_link (QWidget *p) +octave_qt_link::octave_qt_link (QWidget *p, + octave::gui_application *app_context) : octave_link (), main_thread (new QThread ()), - command_interpreter (new octave_interpreter ()) + m_app_context (app_context), + command_interpreter (new octave_interpreter (app_context)) { _current_directory = ""; _new_dir = true; @@ -562,9 +565,12 @@ octave_qt_link::do_set_default_prompts (std::string& ps1, std::string& ps2, std::string& ps4) { - ps1 = ">> "; - ps2 = ""; - ps4 = ""; + if (m_app_context->start_gui_p ()) + { + ps1 = ">> "; + ps2 = ""; + ps4 = ""; + } } void diff -r c3823cb0ea02 -r c2c668b3051b libgui/src/octave-qt-link.h --- a/libgui/src/octave-qt-link.h Mon Jul 11 13:45:12 2016 -0400 +++ b/libgui/src/octave-qt-link.h Sun Jul 10 07:15:21 2016 -0400 @@ -35,6 +35,7 @@ #include #include +#include "octave-gui.h" #include "octave-link.h" #include "octave-interpreter.h" @@ -55,7 +56,7 @@ public: - octave_qt_link (QWidget *p); + octave_qt_link (QWidget *p, octave::gui_application *app_context); ~octave_qt_link (void); @@ -156,6 +157,8 @@ // Thread running octave_main. QThread *main_thread; + octave::gui_application *m_app_context; + octave_interpreter *command_interpreter; QString _current_directory; diff -r c3823cb0ea02 -r c2c668b3051b libinterp/corefcn/dirfns.cc --- a/libinterp/corefcn/dirfns.cc Mon Jul 11 13:45:12 2016 -0400 +++ b/libinterp/corefcn/dirfns.cc Sun Jul 10 07:15:21 2016 -0400 @@ -48,6 +48,7 @@ #include "errwarn.h" #include "input.h" #include "load-path.h" +#include "octave.h" #include "octave-link.h" #include "ovl.h" #include "pager.h" @@ -280,7 +281,9 @@ bool doit = true; - if (interactive && ! forced_interactive && Vconfirm_recursive_rmdir) + if (octave::application::interactive () + && ! octave::application::forced_interactive () + && Vconfirm_recursive_rmdir) { std::string prompt = "remove entire contents of " + fulldir + "? "; diff -r c3823cb0ea02 -r c2c668b3051b libinterp/corefcn/error.cc --- a/libinterp/corefcn/error.cc Mon Jul 11 13:45:12 2016 -0400 +++ b/libinterp/corefcn/error.cc Sun Jul 10 07:15:21 2016 -0400 @@ -36,6 +36,7 @@ #include "defun.h" #include "error.h" #include "input.h" +#include "octave.h" #include "pager.h" #include "ovl.h" #include "oct-map.h" @@ -313,7 +314,8 @@ maybe_enter_debugger (octave_execution_exception& e, bool show_stack_trace = false) { - if ((interactive || forced_interactive) + if ((octave::application::interactive () + || octave::application::forced_interactive ()) && ((Vdebug_on_error && bp_table::debug_on_err (last_error_id ())) || (Vdebug_on_caught && bp_table::debug_on_caught (last_error_id ()))) && octave_call_stack::caller_user_code ()) @@ -720,7 +722,8 @@ && ! discard_warning_messages) pr_where (std::cerr, "warning"); - if ((interactive || forced_interactive) + if ((octave::application::interactive () + || octave::application::forced_interactive ()) && Vdebug_on_warning && in_user_code && bp_table::debug_on_warn (id)) { octave::unwind_protect frame; diff -r c3823cb0ea02 -r c2c668b3051b libinterp/corefcn/input.cc --- a/libinterp/corefcn/input.cc Mon Jul 11 13:45:12 2016 -0400 +++ b/libinterp/corefcn/input.cc Sun Jul 10 07:15:21 2016 -0400 @@ -50,6 +50,7 @@ #include "input.h" #include "lex.h" #include "load-path.h" +#include "octave.h" #include "octave-link.h" #include "oct-map.h" #include "oct-hist.h" @@ -95,13 +96,6 @@ // Character to append after successful command-line completion attempts. static char Vcompletion_append_char = ' '; -// TRUE means this is an interactive shell (either forced or not) -bool interactive = false; - -// TRUE means the user forced this shell to be interactive (-i). -// FALSE means the shell would be interactive, independent of user settings. -bool forced_interactive = false; - // TRUE after a call to completion_matches. bool octave_completion_matches_called = false; @@ -147,9 +141,11 @@ void octave_base_reader::do_input_echo (const std::string& input_string) const { + bool forced_interactive = octave::application::forced_interactive (); + int do_echo = reading_script_file () ? (Vecho_executing_commands & ECHO_SCRIPTS) - : (Vecho_executing_commands & ECHO_CMD_LINE) && ! forced_interactive; + : ((Vecho_executing_commands & ECHO_CMD_LINE) && ! forced_interactive); if (do_echo) { @@ -193,7 +189,7 @@ { Vlast_prompt_time.stamp (); - if (Vdrawnow_requested && interactive) + if (Vdrawnow_requested && octave::application::interactive ()) { bool eval_error = false; @@ -210,7 +206,7 @@ if (! stack_trace.empty ()) std::cerr << stack_trace; - if (interactive) + if (octave::application::interactive ()) recover_from_exception (); } @@ -240,7 +236,7 @@ // Process pre input event hook function prior to flushing output and // printing the prompt. - if (interactive) + if (octave::application::interactive ()) { if (! Vdebugging) octave_link::exit_debugger_event (); @@ -306,7 +302,7 @@ // Process post input event hook function after the internal history // list has been updated. - if (interactive) + if (octave::application::interactive ()) octave_link::post_input_event (); return retval; @@ -601,12 +597,20 @@ frame.protect_var (VPS1); VPS1 = prompt; - if (! interactive) + octave::application *app = octave::application::app (); + + if (! app->interactive ()) { - frame.protect_var (interactive); - interactive = true; - frame.protect_var (forced_interactive); - forced_interactive = true; + + frame.add_method (app, &octave::application::interactive, + app->interactive ()); + + frame.add_method (app, &octave::application::forced_interactive, + app->forced_interactive ()); + + app->interactive (true); + + app->forced_interactive (true); } octave_parser curr_parser; diff -r c3823cb0ea02 -r c2c668b3051b libinterp/corefcn/input.h --- a/libinterp/corefcn/input.h Mon Jul 11 13:45:12 2016 -0400 +++ b/libinterp/corefcn/input.h Sun Jul 10 07:15:21 2016 -0400 @@ -40,13 +40,6 @@ extern OCTINTERP_API FILE *get_input_from_stdin (void); -// TRUE means this is an interactive shell (forced or not) -extern bool interactive; - -// TRUE means the user forced this shell to be interactive (-i). -// FALSE means the shell would be interactive, independent of user settings. -extern bool forced_interactive; - // TRUE after a call to completion_matches. extern bool octave_completion_matches_called; diff -r c3823cb0ea02 -r c2c668b3051b libinterp/corefcn/oct-stream.cc --- a/libinterp/corefcn/oct-stream.cc Mon Jul 11 13:45:12 2016 -0400 +++ b/libinterp/corefcn/oct-stream.cc Sun Jul 10 07:15:21 2016 -0400 @@ -50,6 +50,7 @@ #include "error.h" #include "errwarn.h" #include "input.h" +#include "octave.h" #include "oct-stdstrm.h" #include "oct-stream.h" #include "ov.h" @@ -3989,7 +3990,7 @@ octave_base_stream::do_gets (octave_idx_type max_len, bool& err, bool strip_newline, const std::string& who) { - if (interactive && file_number () == 0) + if (octave::application::interactive () && file_number () == 0) ::error ("%s: unable to read from stdin while running interactively", who.c_str ()); @@ -4100,7 +4101,7 @@ off_t octave_base_stream::skipl (off_t num, bool& err, const std::string& who) { - if (interactive && file_number () == 0) + if (octave::application::interactive () && file_number () == 0) ::error ("%s: unable to read from stdin while running interactively", who.c_str ()); @@ -4568,7 +4569,7 @@ octave_idx_type& conversion_count, const std::string& who) { - if (interactive && file_number () == 0) + if (octave::application::interactive () && file_number () == 0) ::error ("%s: unable to read from stdin while running interactively", who.c_str ()); @@ -4896,7 +4897,9 @@ is.clear (is.rdstate () & (~std::ios::failbit)); // FIXME: is this the right thing to do? - if (interactive && ! forced_interactive && name () == "stdin") + if (octave::application::interactive () + && ! octave::application::forced_interactive () + && name () == "stdin") { is.clear (); @@ -5126,7 +5129,9 @@ // FIXME: is this the right thing to do? - if (interactive && ! forced_interactive && name () == "stdin") + if (octave::application::interactive () + && ! octave::application::forced_interactive () + && name () == "stdin") { // Skip to end of line. bool err; @@ -5218,7 +5223,7 @@ const std::string& who, octave_idx_type& read_count) { - if (interactive && file_number () == 0) + if (octave::application::interactive () && file_number () == 0) ::error ("%s: unable to read from stdin while running interactively", who.c_str ()); diff -r c3823cb0ea02 -r c2c668b3051b libinterp/corefcn/pager.cc --- a/libinterp/corefcn/pager.cc Mon Jul 11 13:45:12 2016 -0400 +++ b/libinterp/corefcn/pager.cc Sun Jul 10 07:15:21 2016 -0400 @@ -38,6 +38,7 @@ #include "error.h" #include "errwarn.h" #include "input.h" +#include "octave.h" #include "ovl.h" #include "pager.h" #include "procstream.h" @@ -232,7 +233,8 @@ int octave_pager_buf::sync (void) { - if (! interactive || forced_interactive + if (! octave::application::interactive () + || octave::application::forced_interactive () || really_flush_to_pager || (Vpage_screen_output && Vpage_output_immediately) || ! Vpage_screen_output) @@ -241,7 +243,8 @@ int len = pptr () - buf; - bool bypass_pager = (! interactive || forced_interactive + bool bypass_pager = (! octave::application::interactive () + || octave::application::forced_interactive () || ! Vpage_screen_output || (really_flush_to_pager && Vpage_screen_output diff -r c3823cb0ea02 -r c2c668b3051b libinterp/corefcn/sighandlers.cc --- a/libinterp/corefcn/sighandlers.cc Mon Jul 11 13:45:12 2016 -0400 +++ b/libinterp/corefcn/sighandlers.cc Sun Jul 10 07:15:21 2016 -0400 @@ -46,6 +46,7 @@ #include "error.h" #include "input.h" #include "load-save.h" +#include "octave.h" #include "oct-map.h" #include "pager.h" #include "pt-bp.h" @@ -523,7 +524,8 @@ octave_signal_caught = 1; octave_interrupt_state++; - if (interactive && ! forced_interactive + if (octave::application::interactive () + && ! octave::application::forced_interactive () && octave_interrupt_state == 2) std::cerr << "Press Control-C again to abort." << std::endl; diff -r c3823cb0ea02 -r c2c668b3051b libinterp/corefcn/sysdep.cc --- a/libinterp/corefcn/sysdep.cc Mon Jul 11 13:45:12 2016 -0400 +++ b/libinterp/corefcn/sysdep.cc Sun Jul 10 07:15:21 2016 -0400 @@ -78,8 +78,9 @@ #include "error.h" #include "errwarn.h" #include "input.h" +#include "octave.h" +#include "ov.h" #include "ovl.h" -#include "ov.h" #include "pager.h" #include "parse.h" #include "sighandlers.h" @@ -341,7 +342,8 @@ int tty_fd = STDIN_FILENO; if (! octave_isatty_wrapper (tty_fd)) { - if (interactive && ! forced_interactive) + if (octave::application::interactive () + && ! octave::application::forced_interactive ()) error ("stdin is not a tty!"); } @@ -722,7 +724,7 @@ // FIXME: add timeout and default value args? - if (interactive) + if (octave::application::interactive ()) { Fdrawnow (); diff -r c3823cb0ea02 -r c2c668b3051b libinterp/corefcn/toplev.cc --- a/libinterp/corefcn/toplev.cc Mon Jul 11 13:45:12 2016 -0400 +++ b/libinterp/corefcn/toplev.cc Sun Jul 10 07:15:21 2016 -0400 @@ -65,6 +65,7 @@ #include "input.h" #include "lex.h" #include "load-save.h" +#include "octave.h" #include "octave-link.h" #include "oct-hist.h" #include "oct-map.h" @@ -685,7 +686,7 @@ // The big loop. - octave_lexer *lxr = (interactive + octave_lexer *lxr = (octave::application::interactive () ? new octave_lexer () : new octave_lexer (stdin)); @@ -713,7 +714,7 @@ octave_quit (); - if (! interactive) + if (! octave::application::interactive ()) { bool quit = (tree_return_command::returning || tree_break_command::breaking); @@ -745,7 +746,7 @@ return exit_status; // Required newline when the user does Ctrl+C at the prompt. - if (interactive) + if (octave::application::interactive ()) octave_stdout << "\n"; } catch (const index_exception& e) @@ -763,7 +764,7 @@ if (! stack_trace.empty ()) std::cerr << stack_trace; - if (interactive) + if (octave::application::interactive ()) recover_from_exception (); else { @@ -790,7 +791,7 @@ } while (retval == 0); - if (interactive) + if (octave::application::interactive ()) octave_stdout << "\n"; if (retval == EOF) @@ -863,7 +864,7 @@ OCTAVE_SAFE_CALL (flush_octave_stdout, ()); - if (! quitting_gracefully && interactive) + if (! quitting_gracefully && octave::application::interactive ()) { octave_stdout << "\n"; diff -r c3823cb0ea02 -r c2c668b3051b libinterp/octave.cc --- a/libinterp/octave.cc Mon Jul 11 13:45:12 2016 -0400 +++ b/libinterp/octave.cc Sun Jul 10 07:15:21 2016 -0400 @@ -87,118 +87,9 @@ extern void install_builtins (void); -int octave_cmdline_argc; -char **octave_cmdline_argv; -int octave_embedded; - -// The command-line options. -static string_vector octave_argv; - -// The name used to invoke Octave. -static std::string octave_program_invocation_name; - -// The last component of octave_program_invocation_name. -static std::string octave_program_name; - -// TRUE means we are using readline. -// (--no-line-editing) -static bool line_editing = true; - -// TRUE means we read ~/.octaverc and ./.octaverc. -// (--norc; --no-init-file; -f) -static bool read_init_files = true; - -// TRUE means we read the site-wide octaverc files. -// (--norc; --no-site-file; -f) -static bool read_site_files = true; - -// TRUE means we set the initial path to configured defaults. -// (--no-init-path) -static bool set_initial_path = true; - -// TRUE means we don't print the usual startup message. -// (--quiet; --silent; -q) -static bool inhibit_startup_message = false; - -// If TRUE, print verbose info in some cases. -// (--verbose; -V) -static bool verbose_flag = false; - -// If TRUE, force the GUI to start. -// (--force-gui) -static bool force_gui_option = false; - -// If TRUE don't start the GUI. -// (--no-gui) -static bool no_gui_option = false; - -// If TRUE, force readline command line editing. -// (--line-editing) -static bool forced_line_editing = false; - -// If TRUE, initialize history list from saved history file. -// (--no-history; -H) -static bool read_history_file = true; - -// The value of "path" specified on the command line. -// (--path; -p) -static std::list command_line_path; - -// The value for "EXEC_PATH" specified on the command line. -// (--exec-path) -static std::string exec_path; - -// The value for "IMAGE_PATH" specified on the command line. -// (--image-path) -static std::string image_path; - -// If TRUE, ignore the window system even if it is available. -// (--no-window-system, -W) -static bool no_window_system = false; - -// The code to evaluate at startup -// (--eval CODE) -static std::string code_to_eval; - -// If TRUE, don't exit after evaluating code given by --eval option. -// (--persist) -static bool persist = false; - -// If TRUE, the GUI should be started. -static bool start_gui = false; - -// If TRUE use traditional (maximally MATLAB compatible) settings -// (--traditional) -static bool traditional = false; - -// TRUE if this is a program and no interpreter and interaction is -// needed. For example, an octave program with shebang line, or code -// from eval without persist. -static bool an_octave_program = false; - // Store the command-line options for later use. static void -intern_argv (int argc, char **argv) -{ - assert (symbol_table::at_top_level ()); - - symbol_table::assign (".nargin.", argc - 1); - - symbol_table::mark_hidden (".nargin."); - - if (argc > 0) - { - octave_argv.resize (argc - 1); - - // Skip program name in argv. - int i = argc; - while (--i > 0) - octave_argv[i-1] = *(argv+i); - } -} - -static void execute_pkg_add (const std::string& dir) { std::string file_name = octave::sys::file_ops::concat (dir, "PKG_ADD"); @@ -230,7 +121,7 @@ } static void -initialize_load_path (void) +initialize_load_path (bool set_initial_path) { // Temporarily set the execute_pkg_add function to one that catches // exceptions. This is better than wrapping load_path::initialize in @@ -346,7 +237,8 @@ // Initialize by reading startup files. static void -execute_startup_files (void) +execute_startup_files (bool read_site_files, bool read_init_files, + bool verbose_flag, bool inhibit_startup_message) { octave::unwind_protect frame; @@ -417,89 +309,6 @@ } } -static int -execute_eval_option_code (const std::string& code) -{ - octave::unwind_protect frame; - - octave_save_signal_mask (); - - octave::can_interrupt = true; - - octave_signal_hook = octave::signal_handler; - octave_interrupt_hook = 0; - octave_bad_alloc_hook = 0; - - octave::catch_interrupts (); - - octave_initialized = true; - - frame.protect_var (interactive); - - interactive = false; - - int parse_status = 0; - - try - { - eval_string (code, false, parse_status, 0); - } - catch (const octave_interrupt_exception&) - { - recover_from_exception (); - - if (quitting_gracefully) - clean_up_and_exit (exit_status); - } - catch (const octave_execution_exception&) - { - recover_from_exception (); - - std::cerr << "error: unhandled execution exception -- eval failed" - << std::endl; - } - - return parse_status; -} - -static void -execute_command_line_file (const std::string& fname) -{ - octave::unwind_protect frame; - - octave_save_signal_mask (); - - octave::can_interrupt = true; - - octave_signal_hook = octave::signal_handler; - octave_interrupt_hook = 0; - octave_bad_alloc_hook = 0; - - octave::catch_interrupts (); - - octave_initialized = true; - - frame.protect_var (interactive); - - frame.protect_var (octave_program_invocation_name); - frame.protect_var (octave_program_name); - - interactive = false; - - octave_program_invocation_name = fname; - - size_t pos = fname.find_last_of (octave::sys::file_ops::dir_sep_chars ()); - - octave_program_name - = (pos != std::string::npos) ? fname.substr (pos+1) : fname; - - std::string context; - bool verbose = false; - bool require_file = true; - - safe_source_file (fname, context, verbose, require_file, "octave"); -} - OCTAVE_NORETURN static void lo_error_handler (const char *fmt, ...) { @@ -536,8 +345,6 @@ static void maximum_braindamage (void) { - persist = true; - FPS1 (octave_value (">> ")); FPS2 (octave_value ("")); FPS4 (octave_value ("")); @@ -560,509 +367,726 @@ disable_warning ("Octave:possible-matlab-short-circuit-operator"); } -// EMBEDDED is declared int instead of bool because this function is -// declared extern "C". +namespace octave +{ + cmdline_options::cmdline_options (void) + { + m_all_args.resize (1); + m_all_args[0] = ""; + } + + cmdline_options::cmdline_options (int argc, char **argv) + { + // Save raw program arguments. + m_all_args = string_vector (argv, argc); + + while (true) + { + int long_idx; + + int optc = octave_getopt_long_wrapper (argc, argv, short_opts, + long_opts, &long_idx); + + if (optc < 0) + break; + + switch (optc) + { + case '?': + // Unrecognized option. getopt_long already printed a message about + // it, so we will just print the usage string and exit. + octave_print_terse_usage_and_exit (); + break; + + case 'H': + Fhistory_save (octave_value (false)); + m_read_history_file = false; + break; + + case 'W': + m_no_window_system = true; + break; + + case 'V': + m_verbose_flag = true; + break; + + case 'd': + // This is the same as yydebug in parse.y. + octave_debug++; + break; + + case 'f': + m_read_init_files = false; + m_read_site_files = false; + break; + + case 'h': + octave_print_verbose_usage_and_exit (); + break; + + case 'i': + m_forced_interactive = true; + break; + + case 'p': + if (optarg) + m_command_line_path.push_back (optarg); + break; + + case 'q': + m_inhibit_startup_message = true; + break; + + case 'x': + { + int val = ECHO_SCRIPTS | ECHO_FUNCTIONS | ECHO_CMD_LINE; + Fecho_executing_commands (octave_value (val)); + } + break; + + case 'v': + octave_print_version_and_exit (); + break; + + case BUILT_IN_DOCSTRINGS_FILE_OPTION: + if (optarg) + Fbuilt_in_docstrings_file (octave_value (optarg)); + break; + + case DOC_CACHE_FILE_OPTION: + if (optarg) + Fdoc_cache_file (octave_value (optarg)); + break; + + case EVAL_OPTION: + if (optarg) + { + if (m_code_to_eval.empty ()) + m_code_to_eval = optarg; + else + m_code_to_eval += std::string (" ") + optarg; + } + break; + + case EXEC_PATH_OPTION: + if (optarg) + m_exec_path = optarg; + break; + + case FORCE_GUI_OPTION: + m_force_gui = true; + break; + + case IMAGE_PATH_OPTION: + if (optarg) + m_image_path = optarg; + break; + + case INFO_FILE_OPTION: + if (optarg) + Finfo_file (octave_value (optarg)); + break; + + case INFO_PROG_OPTION: + if (optarg) + Finfo_program (octave_value (optarg)); + break; + + case DEBUG_JIT_OPTION: + Fdebug_jit (octave_value (true)); + break; + + case JIT_COMPILER_OPTION: + Fjit_enable (octave_value (true)); + break; + + case LINE_EDITING_OPTION: + m_forced_line_editing = m_line_editing = true; + break; + + case NO_GUI_OPTION: + m_no_gui = true; + break; + + case NO_INIT_FILE_OPTION: + m_read_init_files = false; + break; + + case NO_INIT_PATH_OPTION: + m_set_initial_path = false; + break; + + case NO_LINE_EDITING_OPTION: + m_line_editing = false; + break; + + case NO_SITE_FILE_OPTION: + m_read_site_files = 0; + break; + + case PERSIST_OPTION: + m_persist = true; + break; + + case TEXI_MACROS_FILE_OPTION: + if (optarg) + Ftexi_macros_file (octave_value (optarg)); + break; + + case TRADITIONAL_OPTION: + m_traditional = true; + m_persist = true; + break; + + default: + // getopt_long should print a message about unrecognized options and + // return '?', which is handled above. If we end up here, it is + // because there was an option but we forgot to handle it. + // That should be fatal. + panic_impossible (); + break; + } + } + + // Check for various incompatible argument pairs + if (m_force_gui && m_no_gui) + { + warning ("only one of --force-gui and --no-gui may be used"); + + octave_print_terse_usage_and_exit (); + } + + m_remaining_args = string_vector (argv+optind, argc-optind); + } + + cmdline_options::cmdline_options (const cmdline_options& opts) + : m_force_gui (opts.m_force_gui), + m_forced_interactive (opts.m_forced_interactive), + m_forced_line_editing (opts.m_forced_line_editing), + m_inhibit_startup_message (opts.m_inhibit_startup_message), + m_line_editing (opts.m_line_editing), + m_no_gui (opts.m_no_gui), + m_no_window_system (opts.m_no_window_system), + m_persist (opts.m_persist), + m_read_history_file (opts.m_read_history_file), + m_read_init_files (opts.m_read_init_files), + m_read_site_files (opts.m_read_site_files), + m_set_initial_path (opts.m_set_initial_path), + m_traditional (opts.m_traditional), + m_verbose_flag (opts.m_verbose_flag), + m_code_to_eval (opts.m_code_to_eval), + m_command_line_path (opts.m_command_line_path), + m_exec_path (opts.m_exec_path), + m_image_path (opts.m_image_path), + m_all_args (opts.m_all_args), + m_remaining_args (opts.m_remaining_args) + { } + + cmdline_options& + cmdline_options::operator = (const cmdline_options& opts) + { + if (this != &opts) + { + m_force_gui = opts.m_force_gui; + m_forced_interactive = opts.m_forced_interactive; + m_forced_line_editing = opts.m_forced_line_editing; + m_inhibit_startup_message = opts.m_inhibit_startup_message; + m_line_editing = opts.m_line_editing; + m_no_gui = opts.m_no_gui; + m_no_window_system = opts.m_no_window_system; + m_persist = opts.m_persist; + m_read_history_file = opts.m_read_history_file; + m_read_init_files = opts.m_read_init_files; + m_read_site_files = opts.m_read_site_files; + m_set_initial_path = opts.m_set_initial_path; + m_traditional = opts.m_traditional; + m_verbose_flag = opts.m_verbose_flag; + m_code_to_eval = opts.m_code_to_eval; + m_command_line_path = opts.m_command_line_path; + m_exec_path = opts.m_exec_path; + m_image_path = opts.m_image_path; + m_all_args = opts.m_all_args; + m_remaining_args = opts.m_remaining_args; + } + + return *this; + } + + application *application::instance = 0; + + application::application (int argc, char **argv) + : m_options (argc, argv) + { + init (); + } + + application::application (const cmdline_options& opts) + : m_options (opts) + { + init (); + } + + void + application::set_program_names (const std::string& pname) + { + m_program_invocation_name = pname; + + size_t pos = pname.find_last_of (octave::sys::file_ops::dir_sep_chars ()); + + m_program_name = (pos != std::string::npos) ? pname.substr (pos+1) : pname; + } + + void + application::intern_argv (const string_vector& args) + { + assert (symbol_table::at_top_level ()); + + octave_idx_type nargs = args.numel (); + + if (nargs > 0) + { + // Skip first argument (program name). + nargs--; + + m_argv.resize (nargs); + + for (octave_idx_type i = 0; i < nargs; i++) + m_argv[i] = args[i+1]; + } + + symbol_table::assign (".nargin.", nargs); + symbol_table::mark_hidden (".nargin."); + } + + void application::interactive (bool arg) + { + m_interpreter->interactive (arg); + } + + bool application::forced_interactive (void) + { + return instance->m_options.forced_interactive (); + } + + bool application::interactive (void) + { + return instance->m_interpreter->interactive (); + } + + application::~application (void) + { + instance = 0; + + delete m_interpreter; + } + + void application::create_interpreter (void) + { + if (! m_interpreter) + m_interpreter = new interpreter (this); + } + + int application::execute_interpreter (void) + { + return m_interpreter ? m_interpreter->execute () : -1; + } + + void application::init (void) + { + if (instance) + { + // FIXME: Should this be an error? + } + else + instance = this; + + string_vector all_args = m_options.all_args (); + + set_program_names (all_args[0]); + + string_vector remaining_args = m_options.remaining_args (); + + std::string code_to_eval = m_options.code_to_eval (); + + m_have_script_file = ! remaining_args.empty (); + + if (! code_to_eval.empty () && m_have_script_file) + { + warning ("--eval \"CODE\" and script file are mutually exclusive options"); + + octave_print_terse_usage_and_exit (); + } + + m_is_octave_program = ((m_have_script_file || ! code_to_eval.empty ()) + && ! m_options.persist () + && ! m_options.traditional ()); + } + + int cli_application::execute (void) + { + create_interpreter (); + + return execute_interpreter (); + } + + void embedded_application::create_interpreter (void) + { + if (! m_interpreter) + m_interpreter = new interpreter (this, true); + } + + int embedded_application::execute (void) + { + create_interpreter (); + + return execute_interpreter (); + } + + interpreter::interpreter (application *app_context, bool embedded) + : m_app_context (app_context), m_embedded (embedded), + m_interactive (false) + { + cmdline_options options = m_app_context->options (); + + sysdep_init (); + + install_defaults (); + + // Matlab uses "C" locale for LC_NUMERIC class regardless of local setting + setlocale (LC_NUMERIC, "C"); + setlocale (LC_TIME, "C"); + octave::sys::env::putenv ("LC_NUMERIC", "C"); + octave::sys::env::putenv ("LC_TIME", "C"); + + // Initialize the default floating point unit control state. + octave_set_default_fpucw (); + + string_vector all_args = options.all_args (); + + octave_thread::init (); + + set_default_prompts (); + + // Initialize default warning state before --traditional option + // that may reset them. + + initialize_default_warning_state (); + + if (options.traditional ()) + maximum_braindamage (); + + octave_ieee_init (); + + // The idea here is to force xerbla to be referenced so that we will link to + // our own version instead of the one provided by the BLAS library. But + // octave::numeric_limits::NaN () should never be -1, so we + // should never actually call xerbla. FIXME (again!): If this + // becomes a constant expression the test might be optimized away and + // then the reference to the function might also disappear. + + if (octave::numeric_limits::NaN () == -1) + F77_FUNC (xerbla, XERBLA) ("octave", 13 F77_CHAR_ARG_LEN (6)); + + initialize_error_handlers (); + + if (! m_embedded) + octave::install_signal_handlers (); + else + quit_allowed = false; + + initialize_file_io (); + + install_types (); + + install_ops (); + + install_builtins (); + + install_classdef (); + + std::list command_line_path = options.command_line_path (); + + for (std::list::const_iterator it = command_line_path.begin (); + it != command_line_path.end (); it++) + load_path::set_command_line_path (*it); + + std::string exec_path = options.exec_path (); + if (! exec_path.empty ()) + set_exec_path (exec_path); + + std::string image_path = options.image_path (); + if (! image_path.empty ()) + set_image_path (image_path); + + if (options.no_window_system ()) + display_info::no_window_system (); + + // Is input coming from a terminal? If so, we are probably interactive. + + // If stdin is not a tty, then we are reading commands from a pipe or + // a redirected file. + bool stdin_is_tty = octave_isatty_wrapper (fileno (stdin)); + + m_interactive = (! m_embedded + && ! m_app_context->is_octave_program () + && stdin_is_tty + && octave_isatty_wrapper (fileno (stdout))); + + // Check if the user forced an interactive session. If he + // unnecessarily did so, reset forced_interactive to false. + if (options.forced_interactive ()) + { + if (m_interactive) + options.forced_interactive (false); + else + m_interactive = true; + } + + if ((! m_interactive || options.forced_interactive ()) + && ! options.forced_line_editing ()) + options.line_editing (false); + + // Also skip start-up message unless session is interactive. + if (! m_interactive) + options.inhibit_startup_message (true); + + // Force default line editor if we don't want readline editing. + if (! options.line_editing ()) + octave::command_editor::force_default_editor (); + + // These can come after command line args since none of them set any + // defaults that might be changed by command line options. + + if (options.line_editing ()) + initialize_command_input (); + + octave_interpreter_ready = true; + + initialize_version_info (); + + // Make all command-line arguments available to startup files, + // including PKG_ADD files. + + app_context->intern_argv (options.all_args ()); + + initialize_load_path (options.set_initial_path ()); + + initialize_history (options.read_history_file ()); + } + + int interpreter::execute (void) + { + cmdline_options options = m_app_context->options (); + + if (! options.inhibit_startup_message ()) + std::cout << octave_startup_message () << "\n" << std::endl; + + octave_prepare_hdf5 (); + + execute_startup_files (options.read_site_files (), + options.read_init_files (), + options.verbose_flag (), + options.inhibit_startup_message ()); + + if (! options.inhibit_startup_message () + && reading_startup_message_printed) + std::cout << std::endl; + + // Execute any code specified with --eval 'CODE' + std::string code_to_eval = options.code_to_eval (); + + if (! code_to_eval.empty ()) + { + int parse_status = 0; + + try + { + parse_status = execute_eval_option_code (code_to_eval); + } + catch (const octave_execution_exception&) + { + recover_from_exception (); + + parse_status = 1; + } + + if (! options.persist ()) + { + quitting_gracefully = true; + + clean_up_and_exit (parse_status); + } + } + + // If there is an extra argument, see if it names a file to read. + // Additional arguments are taken as command line options for the script. + + if (m_app_context->have_script_file ()) + { + // If we are running an executable script (#! /bin/octave) then + // we should only see the args passed to the script. + + exit_status = 0; + + try + { + string_vector script_args = options.remaining_args (); + + m_app_context->intern_argv (script_args); + + execute_command_line_file (script_args[0]); + } + catch (const octave_execution_exception&) + { + recover_from_exception (); + + exit_status = 1; + } + + // Restore full set of args. + m_app_context->intern_argv (options.all_args ()); + + if (! options.persist ()) + { + quitting_gracefully = true; + + clean_up_and_exit (exit_status); + } + } + + // Avoid counting commands executed from startup or script files. + + octave::command_editor::reset_current_command_number (1); + + // Force input to be echoed if not really interactive, + // but the user has forced interactive behavior. + + if (options.forced_interactive ()) + { + octave::command_editor::blink_matching_paren (false); + + // FIXME: is this the right thing to do? + Fecho_executing_commands (octave_value (ECHO_CMD_LINE)); + } + + if (m_embedded) + { + // FIXME: Do we need to do any cleanup here before returning? + // If we don't, what will happen to Octave functions that have been + // registered to execute with atexit, for example? + + return 1; + } + + int retval = main_loop (); + + quitting_gracefully = true; + + clean_up_and_exit (retval, true); + + return retval; + } + + int interpreter::execute_eval_option_code (const std::string& code) + { + octave::unwind_protect frame; + + octave_save_signal_mask (); + + octave::can_interrupt = true; + + octave_signal_hook = octave::signal_handler; + octave_interrupt_hook = 0; + octave_bad_alloc_hook = 0; + + octave::catch_interrupts (); + + octave_initialized = true; + + frame.add_method (this, &interpreter::interactive, m_interactive); + + m_interactive = false; + + int parse_status = 0; + + try + { + eval_string (code, false, parse_status, 0); + } + catch (const octave_interrupt_exception&) + { + recover_from_exception (); + + if (quitting_gracefully) + clean_up_and_exit (exit_status); + } + catch (const octave_execution_exception&) + { + recover_from_exception (); + + std::cerr << "error: unhandled execution exception -- eval failed" + << std::endl; + } + + return parse_status; + } + + void interpreter::execute_command_line_file (const std::string& fname) + { + octave::unwind_protect frame; + + octave_save_signal_mask (); + + octave::can_interrupt = true; + + octave_signal_hook = octave::signal_handler; + octave_interrupt_hook = 0; + octave_bad_alloc_hook = 0; + + octave::catch_interrupts (); + + octave_initialized = true; + + frame.add_method (this, &interpreter::interactive, m_interactive); + + frame.add_method (m_app_context, + &application::program_invocation_name, + application::program_invocation_name ()); + + frame.add_method (m_app_context, + &application::program_name, + application::program_name ()); + + m_interactive = false; + + m_app_context->set_program_names (fname); + + std::string context; + bool verbose = false; + bool require_file = true; + + safe_source_file (fname, context, verbose, require_file, "octave"); + } +} + +// embedded is int here because octave_main is extern "C". int octave_main (int argc, char **argv, int embedded) { - octave_process_command_line (argc, argv); - - sysdep_init (); - - install_defaults (); - - octave_initialize_interpreter (argc, argv, embedded); - - return octave_execute_interpreter (); -} - -void -octave_process_command_line (int argc, char **argv) -{ - octave_cmdline_argc = argc; - octave_cmdline_argv = argv; - - while (true) - { - int long_idx; - - int optc = octave_getopt_long_wrapper (argc, argv, short_opts, - long_opts, &long_idx); - - if (optc < 0) - break; - - switch (optc) - { - case '?': - // Unrecognized option. getopt_long already printed a message about - // it, so we will just print the usage string and exit. - octave_print_terse_usage_and_exit (); - break; - - case 'H': - Fhistory_save (octave_value (false)); - read_history_file = false; - break; - - case 'W': - no_window_system = true; - break; - - case 'V': - verbose_flag = true; - break; - - case 'd': - // This is the same as yydebug in parse.y. - octave_debug++; - break; - - case 'f': - read_init_files = false; - read_site_files = false; - break; - - case 'h': - octave_print_verbose_usage_and_exit (); - break; - - case 'i': - forced_interactive = true; - break; - - case 'p': - if (optarg) - command_line_path.push_back (optarg); - break; - - case 'q': - inhibit_startup_message = true; - break; - - case 'x': - { - int val = ECHO_SCRIPTS | ECHO_FUNCTIONS | ECHO_CMD_LINE; - Fecho_executing_commands (octave_value (val)); - } - break; - - case 'v': - octave_print_version_and_exit (); - break; - - case BUILT_IN_DOCSTRINGS_FILE_OPTION: - if (optarg) - Fbuilt_in_docstrings_file (octave_value (optarg)); - break; - - case DOC_CACHE_FILE_OPTION: - if (optarg) - Fdoc_cache_file (octave_value (optarg)); - break; - - case EVAL_OPTION: - if (optarg) - { - if (code_to_eval.empty ()) - code_to_eval = optarg; - else - code_to_eval += std::string (" ") + optarg; - } - break; - - case EXEC_PATH_OPTION: - if (optarg) - exec_path = optarg; - break; - - case FORCE_GUI_OPTION: - force_gui_option = true; - break; - - case IMAGE_PATH_OPTION: - if (optarg) - image_path = optarg; - break; - - case INFO_FILE_OPTION: - if (optarg) - Finfo_file (octave_value (optarg)); - break; - - case INFO_PROG_OPTION: - if (optarg) - Finfo_program (octave_value (optarg)); - break; - - case DEBUG_JIT_OPTION: - Fdebug_jit (octave_value (true)); - break; - - case JIT_COMPILER_OPTION: - Fjit_enable (octave_value (true)); - break; - - case LINE_EDITING_OPTION: - forced_line_editing = line_editing = true; - break; - - case NO_GUI_OPTION: - no_gui_option = true; - break; - - case NO_INIT_FILE_OPTION: - read_init_files = false; - break; - - case NO_INIT_PATH_OPTION: - set_initial_path = false; - break; - - case NO_LINE_EDITING_OPTION: - line_editing = false; - break; - - case NO_SITE_FILE_OPTION: - read_site_files = 0; - break; - - case PERSIST_OPTION: - persist = true; - break; - - case TEXI_MACROS_FILE_OPTION: - if (optarg) - Ftexi_macros_file (octave_value (optarg)); - break; - - case TRADITIONAL_OPTION: - traditional = true; - break; - - default: - // getopt_long should print a message about unrecognized options and - // return '?', which is handled above. If we end up here, it is - // because there was an option but we forgot to handle it. - // That should be fatal. - panic_impossible (); - break; - } - } - - // Check for various incompatible argument pairs - if (force_gui_option && no_gui_option) - { - warning ("only one of --force-gui and --no-gui may be used"); - - octave_print_terse_usage_and_exit (); - } - - bool script_file = (argc - optind) > 0; - if (! code_to_eval.empty () && script_file) - { - warning ("--eval \"CODE\" and script file are mutually exclusive options"); - - octave_print_terse_usage_and_exit (); - } - an_octave_program = ((script_file || ! code_to_eval.empty ()) - && ! persist && ! traditional); - -} - -// EMBEDDED is declared int instead of bool because this function is -// declared extern "C". - -void -octave_initialize_interpreter (int argc, char **argv, int embedded) -{ - // Matlab uses "C" locale for LC_NUMERIC class regardless of local setting - setlocale (LC_NUMERIC, "C"); - setlocale (LC_TIME, "C"); - octave::sys::env::putenv ("LC_NUMERIC", "C"); - octave::sys::env::putenv ("LC_TIME", "C"); - - // Initialize the default floating point unit control state - octave_set_default_fpucw (); - - octave_embedded = embedded; - octave::sys::env::set_program_name (argv[0]); - octave_program_invocation_name = octave::sys::env::get_program_invocation_name (); - octave_program_name = octave::sys::env::get_program_name (); - - octave_thread::init (); - - set_default_prompts (); - - // Initialize default warning state before --traditional option - // that may reset them. - - initialize_default_warning_state (); - - if (traditional) - maximum_braindamage (); - - octave_ieee_init (); - - // The idea here is to force xerbla to be referenced so that we will link to - // our own version instead of the one provided by the BLAS library. But - // octave::numeric_limits::NaN () should never be -1, so we - // should never actually call xerbla. FIXME (again!): If this - // becomes a constant expression the test might be optimized away and - // then the reference to the function might also disappear. - - if (octave::numeric_limits::NaN () == -1) - F77_FUNC (xerbla, XERBLA) ("octave", 13 F77_CHAR_ARG_LEN (6)); - - initialize_error_handlers (); - - if (! embedded) - octave::install_signal_handlers (); - else - quit_allowed = false; - - initialize_file_io (); - - install_types (); - - install_ops (); - - install_builtins (); - - install_classdef (); - - for (std::list::const_iterator it = command_line_path.begin (); - it != command_line_path.end (); it++) - load_path::set_command_line_path (*it); - - if (! exec_path.empty ()) - set_exec_path (exec_path); - - if (! image_path.empty ()) - set_image_path (image_path); - - if (no_window_system) - display_info::no_window_system (); - - // Is input coming from a terminal? If so, we are probably interactive. - - // If stdin is not a tty, then we are reading commands from a pipe or - // a redirected file. - bool stdin_is_tty = octave_isatty_wrapper (fileno (stdin)); - - interactive = (! embedded && ! an_octave_program && stdin_is_tty - && octave_isatty_wrapper (fileno (stdout))); - - // Check if the user forced an interactive session. If he - // unnecessarily did so, reset forced_interactive to false. - if (forced_interactive) - { - if (interactive) - forced_interactive = false; - else - interactive = true; - } - - if ((! interactive || forced_interactive) && ! forced_line_editing) - line_editing = false; - - // Also skip start-up message unless session is interactive. - if (! interactive) - inhibit_startup_message = true; - - // Force default line editor if we don't want readline editing. - if (! line_editing) - octave::command_editor::force_default_editor (); - - // These can come after command line args since none of them set any - // defaults that might be changed by command line options. - - if (line_editing) - initialize_command_input (); - - octave_interpreter_ready = true; - - initialize_version_info (); - - // Make all command-line arguments available to startup files, - // including PKG_ADD files. - - intern_argv (argc, argv); - - initialize_load_path (); - - initialize_history (read_history_file); -} - -int -octave_execute_interpreter (void) -{ - if (! inhibit_startup_message) - std::cout << octave_startup_message () << "\n" << std::endl; - - octave_prepare_hdf5 (); - - execute_startup_files (); - - if (! inhibit_startup_message && reading_startup_message_printed) - std::cout << std::endl; - - // Execute any code specified with --eval 'CODE' - if (! code_to_eval.empty ()) + if (embedded) { - int parse_status = 0; - - try - { - parse_status = execute_eval_option_code (code_to_eval); - } - catch (const octave_execution_exception&) - { - recover_from_exception (); - - parse_status = 1; - } - - if (! persist) - { - quitting_gracefully = true; - - clean_up_and_exit (parse_status); - } + octave::embedded_application app (argc, argv); + return app.execute (); } - - // If there is an extra argument, see if it names a file to read. - // Additional arguments are taken as command line options for the script. - - int last_arg_idx = optind; - int remaining_args = octave_cmdline_argc - last_arg_idx; - - if (remaining_args > 0) - { - // If we are running an executable script (#! /bin/octave) then - // we should only see the args passed to the script. - - exit_status = 0; - - try - { - intern_argv (remaining_args, octave_cmdline_argv+last_arg_idx); - - execute_command_line_file (octave_cmdline_argv[last_arg_idx]); - } - catch (const octave_execution_exception&) - { - recover_from_exception (); - - exit_status = 1; - } - - if (! persist) - { - quitting_gracefully = true; - - clean_up_and_exit (exit_status); - } - } - - // Avoid counting commands executed from startup files. - - octave::command_editor::reset_current_command_number (1); - - // Now argv should have the full set of args. - intern_argv (octave_cmdline_argc, octave_cmdline_argv); - - // Force input to be echoed if not really interactive, - // but the user has forced interactive behavior. - - if (forced_interactive) - { - octave::command_editor::blink_matching_paren (false); - - // FIXME: is this the right thing to do? - Fecho_executing_commands (octave_value (ECHO_CMD_LINE)); - } - - if (octave_embedded) + else { - // FIXME: Do we need to do any cleanup here before returning? - // If we don't, what will happen to Octave functions that have been - // registered to execute with atexit, for example? - - return 1; - } - - int retval = main_loop (); - - quitting_gracefully = true; - - clean_up_and_exit (retval, true); - - return retval; -} - -static bool -check_starting_gui (void) -{ - if (no_window_system) - return false; - - std::string err_msg; - if (! display_info::display_available (err_msg)) - { - if (! (inhibit_startup_message || err_msg.empty ())) - warning (err_msg.c_str ()); - - return false; - } - - if (! line_editing) - { - if (! (inhibit_startup_message || no_gui_option)) - warning ("--no-line-editing option given, disabling GUI"); - - return false; + octave::cli_application app (argc, argv); + return app.execute (); } - - if (force_gui_option) - return true; - - if (no_gui_option) - return false; - - if (persist) - return true; - - // If stdin is not a tty, then assume we are reading commands from a pipe or - // a redirected file and the GUI should not start. If this is not the case - // (for example, starting from a desktop "launcher" with no terminal) and you - // want to start the GUI, you may use the --force-gui option to start the GUI. - - if (! octave_isatty_wrapper (fileno (stdin))) - return false; - - // If we have code to eval or execute from a file, and we are going to exit - // immediately after executing it, don't start the gui. - - int last_arg_idx = optind; - int remaining_args = octave_cmdline_argc - last_arg_idx; - - if (! code_to_eval.empty () || remaining_args > 0) - return false; - - return true; -} - -// Return int instead of bool because this function is declared extern "C". - -int -octave_starting_gui (void) -{ - start_gui = check_starting_gui (); - return start_gui; } DEFUN (isguirunning, args, , @@ -1075,7 +1099,10 @@ if (args.length () != 0) print_usage (); - return ovl (start_gui); + // FIXME: This isn't quite right, it just says that we intended to + // start the GUI, not that it is actually running. + + return ovl (octave::application::is_gui_running ()); } /* @@ -1106,7 +1133,7 @@ if (args.length () != 0) print_usage (); - return ovl (Cell (octave_argv)); + return ovl (Cell (octave::application::argv ())); } /* @@ -1129,7 +1156,7 @@ if (args.length () != 0) print_usage (); - return ovl (octave_program_invocation_name); + return ovl (octave::application::program_invocation_name ()); } /* @@ -1148,7 +1175,7 @@ if (args.length () != 0) print_usage (); - return ovl (octave_program_name); + return ovl (octave::application::program_name ()); } /* diff -r c3823cb0ea02 -r c2c668b3051b libinterp/octave.h --- a/libinterp/octave.h Mon Jul 11 13:45:12 2016 -0400 +++ b/libinterp/octave.h Sun Jul 10 07:15:21 2016 -0400 @@ -26,25 +26,353 @@ #include "octave-config.h" #if defined (__cplusplus) + +#include +#include + +#include + +namespace octave +{ + // Command line arguments. See also options-usage.h. + + class OCTINTERP_API cmdline_options + { + public: + + cmdline_options (void); + + cmdline_options (int argc, char **argv); + + cmdline_options (const cmdline_options& opts); + + cmdline_options& operator = (const cmdline_options& opts); + + bool force_gui (void) const { return m_force_gui; } + bool forced_interactive (void) const { return m_forced_interactive; } + bool forced_line_editing (void) const { return m_forced_line_editing; } + bool inhibit_startup_message (void) const { return m_inhibit_startup_message; } + bool line_editing (void) const { return m_line_editing; } + bool no_gui (void) const { return m_no_gui; } + bool no_window_system (void) const { return m_no_window_system; } + bool persist (void) const { return m_persist; } + bool read_history_file (void) const { return m_read_history_file; } + bool read_init_files (void) const { return m_read_init_files; } + bool read_site_files (void) const { return m_read_site_files; } + bool set_initial_path (void) const { return m_set_initial_path; } + bool traditional (void) const { return m_traditional; } + bool verbose_flag (void) const { return m_verbose_flag; } + std::string code_to_eval (void) const { return m_code_to_eval; } + std::list command_line_path (void) const { return m_command_line_path; } + std::string exec_path (void) const { return m_exec_path; } + std::string image_path (void) const { return m_image_path; } + string_vector all_args (void) const { return m_all_args; } + string_vector remaining_args (void) const { return m_remaining_args; } + + void force_gui (bool arg) { m_force_gui = arg; } + void forced_line_editing (bool arg) { m_forced_line_editing = arg; } + void forced_interactive (bool arg) { m_forced_interactive = arg; } + void inhibit_startup_message (bool arg) { m_inhibit_startup_message = arg; } + void line_editing (bool arg) { m_line_editing = arg; } + void no_gui (bool arg) { m_no_gui = arg; } + void no_window_system (bool arg) { m_no_window_system = arg; } + void persist (bool arg) { m_persist = arg; } + void read_history_file (bool arg) { m_read_history_file = arg; } + void read_init_files (bool arg) { m_read_init_files = arg; } + void read_site_files (bool arg) { m_read_site_files = arg; } + void set_initial_path (bool arg) { m_set_initial_path = arg; } + void traditional (bool arg) { m_traditional = arg; } + void verbose_flag (bool arg) { m_verbose_flag = arg; } + void code_to_eval (const std::string& arg) { m_code_to_eval = arg; } + void command_line_path (const std::list& arg) { m_command_line_path = arg; } + void exec_path (const std::string& arg) { m_exec_path = arg; } + void image_path (const std::string& arg) { m_image_path = arg; } + void all_args (const string_vector& arg) { m_all_args = arg; } + void remaining_args (const string_vector& arg) { m_remaining_args = arg; } + + private: + + // If TRUE, force the GUI to start. + // (--force-gui) + bool m_force_gui = false; + + // TRUE means the user forced this shell to be interactive. + // (--interactive, -i) + bool m_forced_interactive = false; + + // If TRUE, force readline command line editing. + // (--line-editing) + bool m_forced_line_editing = false; + + // TRUE means we don't print the usual startup message. + // (--quiet; --silent; -q) + bool m_inhibit_startup_message = false; + + // TRUE means we are using readline. + // (--no-line-editing) + bool m_line_editing = true; + + // If TRUE don't start the GUI. + // (--no-gui) + bool m_no_gui = false; + + // If TRUE, ignore the window system even if it is available. + // (--no-window-system, -W) + bool m_no_window_system = false; + + // If TRUE, don't exit after evaluating code given by --eval option. + // (--persist) + bool m_persist = false; + + // If TRUE, initialize history list from saved history file. + // (--no-history; -H) + bool m_read_history_file = true; + + // TRUE means we read ~/.octaverc and ./.octaverc. + // (--norc; --no-init-file; -f) + bool m_read_init_files = true; + + // TRUE means we read the site-wide octaverc files. + // (--norc; --no-site-file; -f) + bool m_read_site_files = true; + + // TRUE means we set the initial path to configured defaults. + // (--no-init-path) + bool m_set_initial_path = true; + + // If TRUE use traditional (maximally MATLAB compatible) settings + // (--traditional) + bool m_traditional = false; + + // If TRUE, print verbose info in some cases. + // (--verbose; -V) + bool m_verbose_flag = false; + + // The code to evaluate at startup + // (--eval CODE) + std::string m_code_to_eval; + + // The value of "path" specified on the command line. + // (--path; -p) + std::list m_command_line_path; + + // The value for "EXEC_PATH" specified on the command line. + // (--exec-path) + std::string m_exec_path; + + // The value for "IMAGE_PATH" specified on the command line. + // (--image-path) + std::string m_image_path; + + // All arguments passed to the argc, argv constructor. + string_vector m_all_args; + + // Arguments remaining after parsing. + string_vector m_remaining_args; + }; + + // The application object contains a pointer to the current + // interpreter and the interpreter contains a pointer back to the + // application context so we need a forward declaration for one of + // them... + + class interpreter; + + // Base class for an Octave application. + + class OCTINTERP_API application + { + public: + + application (const cmdline_options& opts = cmdline_options ()); + + application (int argc, char **argv); + + virtual ~application (void); + + void set_program_names (const std::string& pname); + + void intern_argv (const string_vector& args); + + cmdline_options options (void) const { return m_options; } + + bool have_script_file (void) const { return m_have_script_file; } + + bool is_octave_program (void) const { return m_is_octave_program; } + + virtual void create_interpreter (void); + + virtual int execute_interpreter (void); + + virtual int execute (void) = 0; + + virtual bool gui_running (void) const { return false; } + virtual void gui_running (bool) { } + + void program_invocation_name (const std::string& nm) { m_program_invocation_name = nm; } + + void program_name (const std::string& nm) { m_program_name = nm; } + + void forced_interactive (bool arg) { m_options.forced_interactive (arg); } + + void interactive (bool arg); + + // Should be an error if instance is 0. + static application *app (void) { return instance; } + + static std::string program_invocation_name (void) { return instance->m_program_invocation_name; } + + static std::string program_name (void) { return instance->m_program_name; } + + static string_vector argv (void) { return instance->m_argv; } + + static bool is_gui_running (void) { return instance->gui_running (); } + + static interpreter *the_interpreter (void) { return instance->m_interpreter; } + + // Convenience functions. + + static bool forced_interactive (void); + static bool interactive (void); + + private: + + // No copying, at least not yet... + + application (const application&); + + application& operator = (const application&); + + // The application instance; There should be only one. + static application *instance; + + void init (void); + + protected: + + // The name used to invoke Octave. + std::string m_program_invocation_name; + + // The last component of octave_program_invocation_name. + std::string m_program_name; + + // The current argument vector (may change if we are running a + // script with --persist because after the script is done, the + // arguments revert to the full list given to the octave + // interpreter at startup. + string_vector m_argv; + + cmdline_options m_options; + + // TRUE if there is a command line argument that looks like the + // name of a file to execute. + bool m_have_script_file = false; + + // TRUE if this is a program and no interpreter and interaction is + // needed. For example, an octave program with shebang line, or code + // from eval without persist. + bool m_is_octave_program = false; + + // If TRUE, the GUI should be started. + bool m_gui_running = false; + + interpreter *m_interpreter = 0; + }; + + class OCTINTERP_API cli_application : public application + { + public: + + cli_application (const cmdline_options& opts = cmdline_options ()) + : application (opts) + { } + + cli_application (int argc, char **argv) + : application (argc, argv) + { } + + ~cli_application (void) { } + + int execute (void); + + private: + + // No copying, at least not yet... + + cli_application (const cli_application&); + + cli_application& operator = (const cli_application&); + }; + + class OCTINTERP_API embedded_application : public application + { + public: + + embedded_application (const cmdline_options& opts = cmdline_options ()) + : application (opts) + { } + + embedded_application (int argc, char **argv) + : application (argc, argv) + { } + + ~embedded_application (void) { } + + void create_interpreter (void); + + int execute (void); + + private: + + // No copying, at least not yet... + + embedded_application (const embedded_application&); + + embedded_application& operator = (const embedded_application&); + }; + + class OCTINTERP_API interpreter + { + public: + + interpreter (application *app_context = 0, bool embedded = false); + + ~interpreter (void) { } + + int execute (void); + + int execute_eval_option_code (const std::string& code); + + void execute_command_line_file (const std::string& fname); + + bool interactive (void) const { return m_interactive; } + void interactive (bool arg) { m_interactive = arg; } + + private: + + // No copying, at least not yet... + + interpreter (const interpreter&); + + interpreter& operator = (const interpreter&); + + application *m_app_context; + + bool m_embedded; + + // TRUE means this is an interactive interpreter (forced or not). + bool m_interactive = false; + }; +} + +#endif + +#if defined (__cplusplus) extern "C" { #endif extern OCTINTERP_API int octave_main (int argc, char **argv, int embedded); -extern OCTINTERP_API void octave_process_command_line (int argc, char **argv); - -extern OCTINTERP_API void -octave_initialize_interpreter (int argc, char **argv, int embedded); - -extern OCTINTERP_API int octave_execute_interpreter (void); - -extern OCTINTERP_API int octave_cmdline_argc; -extern OCTINTERP_API char **octave_cmdline_argv; -extern OCTINTERP_API int octave_embedded; - -extern OCTINTERP_API int octave_starting_gui (void); -extern OCTINTERP_API int octave_fork_gui (void); - #if defined (__cplusplus) } #endif diff -r c3823cb0ea02 -r c2c668b3051b libinterp/parse-tree/lex.ll --- a/libinterp/parse-tree/lex.ll Mon Jul 11 13:45:12 2016 -0400 +++ b/libinterp/parse-tree/lex.ll Sun Jul 10 07:15:21 2016 -0400 @@ -107,6 +107,7 @@ #include "errwarn.h" #include "input.h" #include "lex.h" +#include "octave.h" #include "ov.h" #include "parse.h" #include "pt-all.h" @@ -2321,7 +2322,7 @@ // input. if (! quitting_gracefully - && interactive + && octave::application::interactive () && ! (reading_fcn_file || reading_classdef_file || reading_script_file diff -r c3823cb0ea02 -r c2c668b3051b src/main-cli.cc --- a/src/main-cli.cc Mon Jul 11 13:45:12 2016 -0400 +++ b/src/main-cli.cc Sun Jul 10 07:15:21 2016 -0400 @@ -33,6 +33,8 @@ #include "liboctinterp-build-info.h" +#include "oct-env.h" + #include "defaults.h" #include "octave.h" #include "octave-build-info.h" @@ -81,13 +83,9 @@ { check_hg_versions (); - octave_process_command_line (argc, argv); - - sysdep_init (); + octave::sys::env::set_program_name (argv[0]); - install_defaults (); + octave::cli_application app (argc, argv); - octave_initialize_interpreter (argc, argv, 0); - - return octave_execute_interpreter (); + return app.execute (); } diff -r c3823cb0ea02 -r c2c668b3051b src/main-gui.cc --- a/src/main-gui.cc Mon Jul 11 13:45:12 2016 -0400 +++ b/src/main-gui.cc Sun Jul 10 07:15:21 2016 -0400 @@ -35,6 +35,8 @@ #include "liboctgui-build-info.h" +#include "oct-env.h" + #include "defaults.h" #include "octave.h" #include "octave-build-info.h" @@ -95,13 +97,9 @@ { check_hg_versions (); - octave_process_command_line (argc, argv); - - sysdep_init (); + octave::sys::env::set_program_name (argv[0]); - install_defaults (); + octave::gui_application app (argc, argv); - bool start_gui = octave_starting_gui (); - - return octave_start_gui (argc, argv, start_gui); + return app.execute (); }