changeset 7481:78f3811155f7

use exceptions in liboctave error handler
author John W. Eaton <jwe@octave.org>
date Thu, 14 Feb 2008 17:14:23 -0500
parents 93826ba0d078
children 29980c6b8604
files libcruft/ChangeLog libcruft/misc/cquit.c libcruft/misc/f77-fcn.h libcruft/misc/quit.cc libcruft/misc/quit.h src/ChangeLog src/DLD-FUNCTIONS/urlwrite.cc src/octave.cc src/pt-stmt.cc src/sighandlers.cc src/toplev.cc src/utils.cc
diffstat 12 files changed, 147 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/libcruft/ChangeLog	Wed Feb 13 00:00:33 2008 -0500
+++ b/libcruft/ChangeLog	Thu Feb 14 17:14:23 2008 -0500
@@ -1,3 +1,18 @@
+2008-02-14  John W. Eaton  <jwe@octave.org>
+
+	* misc/f77-fcn.h (F77_XFCN): Call octave_rethrow_exception here
+	instead of checking octave_allocation_error.
+	* misc/quit.cc (octave_execution_exception): New function.
+	(octave_rethrow_exception): New function.
+	(octave_handle_signal): Call octave_rethrow_exception instead of
+	octave_throw_interrupt_exception.
+	* misc/quit.h (octave_execution_error): New variable.
+	(END_INTERRUPT_WITH_EXCEPTIONS): Catch octave_execution_exception.
+	(octave_execution_exception): New class.
+	(octave_exception): New enum.
+	(octave_exception_state): Rename from octave_allocation_error.
+	Change all uses.
+
 2008-02-12  John W. Eaton  <jwe@octave.org>
 
 	* lapack-xtra/xilaenv.f: New wrapper for Fortran function ilaenv.
--- a/libcruft/misc/cquit.c	Wed Feb 13 00:00:33 2008 -0500
+++ b/libcruft/misc/cquit.c	Thu Feb 14 17:14:23 2008 -0500
@@ -255,7 +255,7 @@
 
 sig_atomic_t octave_interrupt_state = 0;
 
-sig_atomic_t octave_allocation_error = 0;
+sig_atomic_t octave_exception_state = 0;
 
 sig_atomic_t octave_signal_caught = 0;
 
--- a/libcruft/misc/f77-fcn.h	Wed Feb 13 00:00:33 2008 -0500
+++ b/libcruft/misc/f77-fcn.h	Thu Feb 14 17:14:23 2008 -0500
@@ -62,10 +62,8 @@
           octave_restore_current_context (saved_context); \
 	  if (f77_exception_encountered) \
 	    F77_XFCN_ERROR (f, F); \
-          else if (octave_allocation_error) \
-            octave_throw_bad_alloc (); \
           else \
-            octave_throw_interrupt_exception (); \
+	    octave_rethrow_exception (); \
 	} \
       else \
         { \
--- a/libcruft/misc/quit.cc	Wed Feb 13 00:00:33 2008 -0500
+++ b/libcruft/misc/quit.cc	Thu Feb 14 17:14:23 2008 -0500
@@ -58,14 +58,49 @@
 }
 
 void
+octave_throw_execution_exception (void)
+{
+  // FIXME -- would a hook function be useful here?
+
+  octave_exception_state = octave_exec_exception;
+    
+  throw octave_execution_exception ();
+}
+
+void
 octave_throw_bad_alloc (void)
 {
   if (octave_bad_alloc_hook)
     octave_bad_alloc_hook ();
     
+  octave_exception_state = octave_alloc_exception;
+
   throw std::bad_alloc ();
 }
 
+void
+octave_rethrow_exception (void)
+{
+  if (octave_interrupt_state)
+    octave_throw_interrupt_exception ();
+  else
+    {
+      switch (octave_exception_state)
+	{
+	case octave_exec_exception:
+	  octave_throw_execution_exception ();
+	  break;
+
+	case octave_alloc_exception:
+	  octave_throw_bad_alloc ();
+	  break;
+
+	default:
+	  break;
+	}
+    }
+}
+
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/libcruft/misc/quit.h	Wed Feb 13 00:00:33 2008 -0500
+++ b/libcruft/misc/quit.h	Thu Feb 14 17:14:23 2008 -0500
@@ -74,11 +74,23 @@
 
 #ifdef __cplusplus
 class
+octave_execution_exception
+{
+};
+
+class
 octave_interrupt_exception
 {
 };
 #endif
 
+enum octave_exception
+{
+  octave_no_exception = 0,
+  octave_exec_exception = 1,
+  octave_alloc_exception = 2
+};
+
 CRUFT_API extern sig_atomic_t octave_interrupt_immediately;
 
 /*
@@ -88,7 +100,7 @@
 */
 CRUFT_API extern sig_atomic_t octave_interrupt_state;
 
-CRUFT_API extern sig_atomic_t octave_allocation_error;
+CRUFT_API extern sig_atomic_t octave_exception_state;
 
 CRUFT_API extern sig_atomic_t octave_signal_caught;
 
@@ -96,8 +108,12 @@
 
 CRUFT_API extern void octave_throw_interrupt_exception (void) GCC_ATTR_NORETURN;
 
+CRUFT_API extern void octave_throw_execution_exception (void) GCC_ATTR_NORETURN;
+
 CRUFT_API extern void octave_throw_bad_alloc (void) GCC_ATTR_NORETURN;
 
+CRUFT_API extern void octave_rethrow_exception (void) GCC_ATTR_NORETURN;
+
 #define OCTAVE_QUIT \
   do \
     { \
@@ -119,7 +135,7 @@
 
      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_1;
      ... custom code here, normally ending in a call to
-         octave_throw_interrupt_exception ...
+         octave_rethrow_exception ...
      BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_2;
 
    so that you can perform extra clean up operations before throwing
@@ -127,7 +143,7 @@
 
 #define BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE \
   BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_1; \
-  octave_throw_interrupt_exception (); \
+  octave_rethrow_exception (); \
   BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_2
 
 #define BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_1 \
@@ -170,10 +186,16 @@
       octave_interrupt_immediately = saved_octave_interrupt_immediately; \
       octave_jump_to_enclosing_context (); \
     } \
+  catch (octave_execution_exception) \
+    { \
+      octave_interrupt_immediately = saved_octave_interrupt_immediately; \
+      octave_exception_state = octave_exec_exception; \
+      octave_jump_to_enclosing_context (); \
+    } \
   catch (std::bad_alloc) \
     { \
       octave_interrupt_immediately = saved_octave_interrupt_immediately; \
-      octave_allocation_error = 1; \
+      octave_exception_state = octave_alloc_exception; \
       octave_jump_to_enclosing_context (); \
     } \
  \
--- a/src/ChangeLog	Wed Feb 13 00:00:33 2008 -0500
+++ b/src/ChangeLog	Thu Feb 14 17:14:23 2008 -0500
@@ -1,3 +1,19 @@
+2008-02-14  John W. Eaton  <jwe@octave.org>
+
+	* sighandlers.cc (user_abort): If interrupting immediately, set
+	octave_interrupt_state if it is not already set.
+
+	* pt-stmt.cc (tree_statement::eval): Catch execution exceptions.
+
+	* octave.cc (lo_error_handler): New static function.
+	(initialize_error_handlers): Set liboctave_error_handler to
+	lo_error_handler, not error.
+
+	* DLD-FUNCTIONS/urlwrite.cc (urlget): Call octave_rethrow_exception
+	instead of octave_throw_interrupt_exception.
+	* utils.cc (BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_FOR_VSNPRINTF): 
+	Likewise.
+
 2008-02-12  David Bateman  <dbateman@free.fr>
 
 	* graphics.h.in: Implement the cdatamapping property in patch and
--- a/src/DLD-FUNCTIONS/urlwrite.cc	Wed Feb 13 00:00:33 2008 -0500
+++ b/src/DLD-FUNCTIONS/urlwrite.cc	Thu Feb 14 17:14:23 2008 -0500
@@ -167,7 +167,7 @@
 
   res = CURLE_ABORTED_BY_CALLBACK;
   urlget_cleanup (curl);
-  octave_throw_interrupt_exception ();
+  octave_rethrow_exception ();
 
   BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_2;
 
--- a/src/octave.cc	Wed Feb 13 00:00:33 2008 -0500
+++ b/src/octave.cc	Thu Feb 14 17:14:23 2008 -0500
@@ -525,9 +525,20 @@
 }
 
 static void
+lo_error_handler (const char *fmt, ...)
+{
+  va_list args;
+  va_start (args, fmt);
+  verror (fmt, args);
+  va_end (args);
+
+  octave_throw_execution_exception ();
+}
+
+static void
 initialize_error_handlers ()
 {
-  set_liboctave_error_handler (error);
+  set_liboctave_error_handler (lo_error_handler);
   set_liboctave_warning_handler (warning);
   set_liboctave_warning_with_id_handler (warning_with_id);
 }
--- a/src/pt-stmt.cc	Wed Feb 13 00:00:33 2008 -0500
+++ b/src/pt-stmt.cc	Thu Feb 14 17:14:23 2008 -0500
@@ -98,36 +98,44 @@
 
       maybe_echo_code (in_function_body);
 
-      if (cmd)
-	cmd->eval ();
-      else
+      try
 	{
-	  expr->set_print_flag (pf);
+	  if (cmd)
+	    cmd->eval ();
+	  else
+	    {
+	      expr->set_print_flag (pf);
 
-	  // FIXME -- maybe all of this should be packaged in
-	  // one virtual function that returns a flag saying whether
-	  // or not the expression will take care of binding ans and
-	  // printing the result.
+	      // FIXME -- maybe all of this should be packaged in
+	      // one virtual function that returns a flag saying whether
+	      // or not the expression will take care of binding ans and
+	      // printing the result.
 
-	  // FIXME -- it seems that we should just have to
-	  // call expr->rvalue () and that should take care of
-	  // everything, binding ans as necessary?
+	      // FIXME -- it seems that we should just have to
+	      // call expr->rvalue () and that should take care of
+	      // everything, binding ans as necessary?
+
+	      bool do_bind_ans = false;
 
-	  bool do_bind_ans = false;
+	      if (expr->is_identifier ())
+		{
+		  tree_identifier *id = dynamic_cast<tree_identifier *> (expr);
 
-	  if (expr->is_identifier ())
-	    {
-	      tree_identifier *id = dynamic_cast<tree_identifier *> (expr);
+		  do_bind_ans = (! id->is_variable ());
+		}
+	      else
+		do_bind_ans = (! expr->is_assignment_expression ());
 
-	      do_bind_ans = (! id->is_variable ());
+	      retval = expr->rvalue (nargout);
+
+	      if (do_bind_ans && ! (error_state || retval.empty ()))
+		bind_ans (retval(0), pf);
 	    }
-	  else
-	    do_bind_ans = (! expr->is_assignment_expression ());
-
-	  retval = expr->rvalue (nargout);
-
-	  if (do_bind_ans && ! (error_state || retval.empty ()))
-	    bind_ans (retval(0), pf);
+	}
+      catch (octave_execution_exception)
+	{
+	  octave_exception_state = octave_no_exception;
+	  error ("caught execution error in library function");
 	}
 
       unwind_protect::run ();
--- a/src/sighandlers.cc	Wed Feb 13 00:00:33 2008 -0500
+++ b/src/sighandlers.cc	Thu Feb 14 17:14:23 2008 -0500
@@ -357,7 +357,7 @@
 // for SIGINT only.
 
 static
-void user_abort(const char *sig_name, int sig_number)
+void user_abort (const char *sig_name, int sig_number)
 {
   if (! octave_initialized)
     exit (1);
@@ -378,7 +378,12 @@
 	}
 
       if (octave_interrupt_immediately)
-	octave_jump_to_enclosing_context ();
+	{
+	  if (octave_interrupt_state == 0)
+	    octave_interrupt_state = 1;
+
+	  octave_jump_to_enclosing_context ();
+	}
       else
 	{
 	  // If we are already cleaning up from a previous interrupt,
--- a/src/toplev.cc	Wed Feb 13 00:00:33 2008 -0500
+++ b/src/toplev.cc	Thu Feb 14 17:14:23 2008 -0500
@@ -182,7 +182,7 @@
   octave_interrupt_immediately = 0;
   octave_interrupt_state = 0;
   octave_signal_caught = 0;
-  octave_allocation_error = 0;
+  octave_exception_state = octave_no_exception;
   octave_restore_signal_mask ();
   octave_catch_interrupts ();
 }
--- a/src/utils.cc	Wed Feb 13 00:00:33 2008 -0500
+++ b/src/utils.cc	Thu Feb 14 17:14:23 2008 -0500
@@ -966,7 +966,7 @@
   delete [] buf; \
   buf = 0; \
   size = initial_size; \
-  octave_throw_interrupt_exception (); \
+  octave_rethrow_exception (); \
   BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_2
 
 #if defined __GNUC__ && defined __va_copy