changeset 12011:67ad3b58b99a release-3-2-x

improve error handling
author Jaroslav Hajek <highegg@gmail.com>
date Wed, 24 Jun 2009 07:31:32 +0200
parents 00b55509f5b5
children 664597f88284
files src/ChangeLog src/octave.cc src/pt-eval.cc src/toplev.cc src/toplev.h
diffstat 5 files changed, 57 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,15 @@
+2009-06-23  Jaroslav Hajek  <highegg@gmail.com>
+
+	* quit.h (octave_quit_exception): Delete.
+	(exit_status, quitting_gracefully): New globals.
+	* quit.cc: Initialize them.
+	(Fquit): Set the globals, simulate interrupt.
+	(main_loop): Handle exit properly.
+	* octave.cc (execute_eval_option_code): Ditto.
+	(execute_command_line_file): Ditto.
+	* pt-eval.cc (do_unwind_protect_cleanup_code):
+	Fix order of unwind_protect calls.
+
 2009-06-23  John W. Eaton  <jwe@octave.org>
 
 	* oct-map.cc (Octave_map::squeeze, Octave_map::permute,
--- a/src/octave.cc
+++ b/src/octave.cc
@@ -394,15 +394,12 @@
     {
       eval_string (code, false, parse_status, 0);
     }
-  catch (octave_quit_exception e)
-    {
-      unwind_protect::run_frame ("execute_eval_option_code");
-      clean_up_and_exit (e.status);
-    }
   catch (octave_interrupt_exception)
     {
       recover_from_exception ();
       octave_stdout << "\n";
+      if (quitting_gracefully)
+        clean_up_and_exit (exit_status);
     }
   catch (std::bad_alloc)
     {
@@ -466,15 +463,12 @@
 
       source_file (fname, context, verbose, require_file, "octave");
     }
-  catch (octave_quit_exception e)
-    {
-      unwind_protect::run_frame ("execute_command_line_file");
-      clean_up_and_exit (e.status);
-    }
   catch (octave_interrupt_exception)
     {
       recover_from_exception ();
       octave_stdout << "\n";
+      if (quitting_gracefully)
+        clean_up_and_exit (exit_status);
     }
   catch (std::bad_alloc)
     {
--- a/src/pt-eval.cc
+++ b/src/pt-eval.cc
@@ -909,6 +909,9 @@
 {
   tree_statement_list *list = static_cast<tree_statement_list *> (ptr);
 
+  unwind_protect_int (octave_interrupt_state);
+  octave_interrupt_state = 0;
+
   // We want to run the cleanup code without error_state being set,
   // but we need to restore its value, so that any errors encountered
   // in the first part of the unwind_protect are not completely
@@ -917,9 +920,6 @@
   unwind_protect_int (error_state);
   error_state = 0;
 
-  unwind_protect_int (octave_interrupt_state);
-  octave_interrupt_state = 0;
-
   // Similarly, if we have seen a return or break statement, allow all
   // the cleanup code to run before returning or handling the break.
   // We don't have to worry about continue statements because they can
--- a/src/toplev.cc
+++ b/src/toplev.cc
@@ -85,7 +85,9 @@
 bool quit_allowed = true;
 
 // TRUE means we are exiting via the builtin exit or quit functions.
-static bool quitting_gracefully = false;
+bool quitting_gracefully = false;
+// This stores the exit status.
+int exit_status = 0;
 
 // TRUE means we are ready to interpret commands, but not everything
 // is ready for interactive use.
@@ -613,15 +615,15 @@
 
 	  unwind_protect::run_frame ("main_loop");
 	}
-      catch (octave_quit_exception e)
-        {
-          unwind_protect::run_all ();
-          clean_up_and_exit (e.status);
-        }
       catch (octave_interrupt_exception)
 	{
 	  recover_from_exception ();
-	  octave_stdout << "\n";
+          octave_stdout << "\n";
+          if (quitting_gracefully)
+            {
+              clean_up_and_exit (exit_status);
+              break; // If user has overriden the exit func.
+            }
 	}
       catch (octave_execution_exception)
 	{
@@ -671,10 +673,6 @@
     error ("quit: not supported in embedded mode.");
   else if (nargout == 0)
     {
-      int exit_status = 0;
-
-      quitting_gracefully = true;
-
       if (args.length () > 0)
 	{
 	  int tmp = args(0).nint_value ();
@@ -683,7 +681,16 @@
 	    exit_status = tmp;
 	}
 
-      throw octave_quit_exception (exit_status);
+      if (! error_state)
+        {
+          quitting_gracefully = true;
+
+          // Simulate interrupt.
+
+          octave_interrupt_state = -1;
+
+          octave_throw_interrupt_exception ();
+        }
     }
   else
     error ("quit: invalid number of output arguments");
@@ -984,7 +991,22 @@
 
       reset_error_handler ();
 
-      feval (fcn, octave_value_list (), 0);
+      try
+        {
+          feval (fcn, octave_value_list (), 0);
+        }
+      catch (octave_interrupt_exception)
+	{
+	  recover_from_exception ();
+	}
+      catch (octave_execution_exception)
+	{
+	  recover_from_exception ();
+	}
+      catch (std::bad_alloc)
+	{
+	  recover_from_exception ();
+	}
 
       flush_octave_stdout ();
     }
--- a/src/toplev.h
+++ b/src/toplev.h
@@ -48,15 +48,9 @@
 
 extern OCTINTERP_API bool quit_allowed;
 
-// quit is a lot like an interrupt, so we subclass it to simplify possible
-// handling.
-class octave_quit_exception 
-: public octave_interrupt_exception
-{
-public:
-  int status;
-  octave_quit_exception (int s) : status (s) { }
-};
+extern OCTINTERP_API bool quitting_gracefully;
+
+extern OCTINTERP_API int exit_status;
 
 extern OCTINTERP_API void
 clean_up_and_exit (int);