diff libinterp/corefcn/interpreter.cc @ 23092:0fed4c678795

additional restructuring of startup and shutdown * main-window.h, main-window.cc (main_window::~main_window): Don't delete _octave_qt_link here. (main_window::exit_app): Delete. (main_window::construct_octave_qt_link): Delete connection from octave_qt_link::exit_app_signal to main_window::exit_app slot. Call octave_link::connect_link immediately after constructing new octave_qt_link_object. * octave-interpreter.h, octave-interpreter.cc (octave_interpreter::m_exit_status): Delete unused data member. (octave_interpreter::execute): Call qApp->exit here. * octave-link.h (octave_link::do_exit): Delete. (octave_link::exit): Delete. (octave_link::disconnect_link, octave_link::enable, octave_link::disable, octave_link::do_enable, octave_link::do_disable): New functions. (octave_link::process_events): Call do_disable instead of accessing link_enabled directly. (octave_link::confirm_shutdown): Check enabled, not instance_ok. * octave-qt-link.h, octave-qt-link.cc (octave_qt_link::do_exit): Delete. (octave_qt_link::exit_app_signal): Delete. * interpreter.h, interpreter.cc (interpreter::execute_internal): New function. Perform interpreter::execute actions here. Simply handle If not in persist mode, simply return status from execute_eval_option_code and execute_command_line_file. Simply return status from main_loop. Don't set m_quitting_gracefully here. (interpreter::execute): Wrap interpreter::execute_internal in try-catch block. If exit_exception is caught, process octave_link events and disconnect link here. Call cleanup here, not from destructor. (interpreter::m_quitting_gracefully): Delete data member and all uses. (safe_source_file, execute_pkg_add): Don't catch index_exception. Dopn't display message for execution_exception. (initialize_load_path, execute_startup_files): Return status from safe_source_file. Don't fail, but preserve any non-zero status. (interpreter::execute_eval_option_code): Don't catch exit_exception here. (interpreter::main_loop): Don't print extra newline when interactive main loop is done. (interpreter::cleanup): Don't call raw_mode.
author John W. Eaton <jwe@octave.org>
date Thu, 26 Jan 2017 08:26:46 -0500
parents 9f406f0b36da
children a40e586b66ba
line wrap: on
line diff
--- a/libinterp/corefcn/interpreter.cc	Wed Jan 25 16:11:51 2017 -0800
+++ b/libinterp/corefcn/interpreter.cc	Thu Jan 26 08:26:46 2017 -0500
@@ -362,15 +362,6 @@
     {
       octave::source_file (file_name, context, verbose, require_file, warn_for);
     }
-  catch (const octave::index_exception& e)
-    {
-      recover_from_exception ();
-
-      std::cerr << "error: index exception in " << file_name << ": "
-                << e.message () << std::endl;
-
-      return 1;
-    }
   catch (const octave::interrupt_exception&)
     {
       recover_from_exception ();
@@ -381,8 +372,6 @@
     {
       recover_from_exception ();
 
-      std::cerr << "error: execution exception in " << file_name << std::endl;
-
       return 1;
     }
 
@@ -398,13 +387,6 @@
     {
       load_path::execute_pkg_add (dir);
     }
-  catch (const octave::index_exception& e)
-    {
-      recover_from_exception ();
-
-      std::cerr << "error: index exception in " << file_name << ": "
-                << e.message () << std::endl;
-    }
   catch (const octave::interrupt_exception&)
     {
       recover_from_exception ();
@@ -412,8 +394,6 @@
   catch (const octave::execution_exception&)
     {
       recover_from_exception ();
-
-      std::cerr << "error: execution exception in " << file_name << std::endl;
     }
 }
 
@@ -437,9 +417,11 @@
   load_path::initialize (set_initial_path);
 }
 
-// Initialize by reading startup files.
+// Initialize by reading startup files.  Return non-zero if an exception
+// occurs when reading any of them, but don't exit early because of an
+// exception.
 
-static void
+static int
 execute_startup_files (bool read_site_files, bool read_init_files,
                        bool verbose_flag, bool inhibit_startup_message)
 {
@@ -451,6 +433,8 @@
 
   bool require_file = false;
 
+  int exit_status = 0;
+
   if (read_site_files)
     {
       // Execute commands from the site-wide configuration file.
@@ -458,10 +442,17 @@
       // (if it exists), then from the file
       // $(prefix)/share/octave/$(version)/m/octaverc (if it exists).
 
-      safe_source_file (Vlocal_site_defaults_file, context, verbose,
-                        require_file);
+      int status = safe_source_file (Vlocal_site_defaults_file, context,
+                                     verbose, require_file);
+
+      if (status)
+        exit_status = status;
 
-      safe_source_file (Vsite_defaults_file, context, verbose, require_file);
+      status = safe_source_file (Vsite_defaults_file, context, verbose,
+                                 require_file);
+
+      if (status)
+        exit_status = status;
     }
 
   if (read_init_files)
@@ -485,7 +476,11 @@
 
       if (! home_rc.empty ())
         {
-          safe_source_file (home_rc, context, verbose, require_file);
+          int status = safe_source_file (home_rc, context, verbose,
+                                         require_file);
+
+          if (status)
+            exit_status = status;
 
           // Names alone are not enough.
 
@@ -507,9 +502,15 @@
           if (local_rc.empty ())
             local_rc = octave::sys::env::make_absolute (initfile);
 
-          safe_source_file (local_rc, context, verbose, require_file);
+          int status = safe_source_file (local_rc, context, verbose,
+                                         require_file);
+
+          if (status)
+            exit_status = status;
         }
     }
+
+  return exit_status;
 }
 
 namespace octave
@@ -518,8 +519,7 @@
 
   interpreter::interpreter (application *app_context, bool embedded)
     : m_app_context (app_context), m_evaluator (new tree_evaluator (this)),
-      m_embedded (embedded), m_interactive (false),
-      m_quitting_gracefully (false)
+      m_embedded (embedded), m_interactive (false)
   {
     current_evaluator = m_evaluator;
 
@@ -639,8 +639,6 @@
 
   interpreter::~interpreter (void)
   {
-    cleanup ();
-
     current_evaluator = 0;
 
     delete m_evaluator;
@@ -648,6 +646,24 @@
 
   int interpreter::execute (void)
   {
+    int exit_status = 0;
+
+    try
+      {
+        exit_status = execute_internal ();
+      }
+    catch (const octave::exit_exception& ex)
+      {
+        exit_status = ex.exit_status ();
+      }
+
+    cleanup ();
+
+    return exit_status;
+  }
+
+  int interpreter::execute_internal (void)
+  {
     cmdline_options options = m_app_context->options ();
 
     if (m_interactive && ! options.inhibit_startup_message ())
@@ -655,10 +671,18 @@
 
     octave_prepare_hdf5 ();
 
-    execute_startup_files (options.read_site_files (),
-                           options.read_init_files (),
-                           options.verbose_flag (),
-                           options.inhibit_startup_message ());
+    // Don't fail, but return non-zero if there is an error in a startup
+    // file.
+
+    int exit_status = 0;
+
+    int status = execute_startup_files (options.read_site_files (),
+                                        options.read_init_files (),
+                                        options.verbose_flag (),
+                                        options.inhibit_startup_message ());
+
+    if (status)
+      exit_status = status;
 
     if (m_interactive && ! options.inhibit_startup_message ()
         && reading_startup_message_printed)
@@ -669,25 +693,13 @@
 
     if (! code_to_eval.empty ())
       {
-        int exit_status = 0;
+        status = execute_eval_option_code (code_to_eval);
 
-        try
-          {
-            exit_status = execute_eval_option_code (code_to_eval);
-          }
-        catch (const octave::exit_exception& ex)
-          {
-            recover_from_exception ();
-
-            return ex.exit_status ();
-          }
+        if (status)
+          exit_status = status;
 
         if (! options.persist ())
-          {
-            m_quitting_gracefully = true;
-
-            return exit_status;
-          }
+          return exit_status;
       }
 
     // If there is an extra argument, see if it names a file to read.
@@ -698,32 +710,20 @@
         // If we are running an executable script (#! /bin/octave) then
         // we should only see the args passed to the script.
 
-        int exit_status = 0;
+        string_vector script_args = options.remaining_args ();
 
-        try
-          {
-            string_vector script_args = options.remaining_args ();
-
-            m_app_context->intern_argv (script_args);
+        m_app_context->intern_argv (script_args);
 
-            exit_status = execute_command_line_file (script_args[0]);
-          }
-        catch (const octave::exit_exception& ex)
-          {
-            recover_from_exception ();
+        status = execute_command_line_file (script_args[0]);
 
-            return ex.exit_status ();
-          }
+        if (status)
+          exit_status = status;
 
         // Restore full set of args.
         m_app_context->intern_argv (options.all_args ());
 
         if (! options.persist ())
-          {
-            m_quitting_gracefully = true;
-
-            return exit_status;
-          }
+          return exit_status;
       }
 
     // Avoid counting commands executed from startup or script files.
@@ -750,11 +750,7 @@
         return 1;
       }
 
-    int retval = main_loop ();
-
-    m_quitting_gracefully = true;
-
-    return retval;
+    return main_loop ();
   }
 
   int interpreter::execute_eval_option_code (const std::string& code)
@@ -904,16 +900,6 @@
                   break;
               }
           }
-        catch (const octave::exit_exception& ex)
-          {
-            recover_from_exception ();
-
-            // If we are connected to a gui, allow it to manage the exit
-            // process.
-            octave_link::exit (ex.exit_status ());
-
-            return ex.exit_status ();
-          }
         catch (const octave::interrupt_exception&)
           {
             recover_from_exception ();
@@ -964,9 +950,6 @@
       }
     while (retval == 0);
 
-    if (octave::application::interactive ())
-      octave_stdout << "\n";
-
     if (retval == EOF)
       retval = 0;
 
@@ -977,6 +960,12 @@
   {
     static bool deja_vu = false;
 
+    // If we are attached to a GUI, process pending events and
+    // disconnect the link.
+
+    octave_link::process_events (true);
+    octave_link::disconnect_link ();
+
     OCTAVE_SAFE_CALL (remove_input_event_hook_functions, ());
 
     while (! octave_atexit_functions.empty ())
@@ -1003,9 +992,6 @@
 
         OCTAVE_SAFE_CALL (octave::command_editor::restore_terminal_state, ());
 
-        // FIXME: is this needed?  Can it cause any trouble?
-        OCTAVE_SAFE_CALL (raw_mode, (0));
-
         OCTAVE_SAFE_CALL (octave_history_write_timestamp, ());
 
         if (! octave::command_history::ignoring_entries ())
@@ -1027,7 +1013,7 @@
 
         OCTAVE_SAFE_CALL (octave::flush_stdout, ());
 
-        if (! m_quitting_gracefully && octave::application::interactive ())
+        if (octave::application::interactive ())
           {
             octave_stdout << "\n";