# HG changeset patch # User John W. Eaton # Date 1203027263 18000 # Node ID 78f3811155f745e7fc41e9025da3da10dbfd6c4a # Parent 93826ba0d07898c881df59c7ad9d3df2597ea4c5 use exceptions in liboctave error handler diff -r 93826ba0d078 -r 78f3811155f7 libcruft/ChangeLog --- 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 + + * 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 * lapack-xtra/xilaenv.f: New wrapper for Fortran function ilaenv. diff -r 93826ba0d078 -r 78f3811155f7 libcruft/misc/cquit.c --- 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; diff -r 93826ba0d078 -r 78f3811155f7 libcruft/misc/f77-fcn.h --- 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 \ { \ diff -r 93826ba0d078 -r 78f3811155f7 libcruft/misc/quit.cc --- 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++ *** diff -r 93826ba0d078 -r 78f3811155f7 libcruft/misc/quit.h --- 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 (); \ } \ \ diff -r 93826ba0d078 -r 78f3811155f7 src/ChangeLog --- 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 + + * 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 * graphics.h.in: Implement the cdatamapping property in patch and diff -r 93826ba0d078 -r 78f3811155f7 src/DLD-FUNCTIONS/urlwrite.cc --- 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; diff -r 93826ba0d078 -r 78f3811155f7 src/octave.cc --- 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); } diff -r 93826ba0d078 -r 78f3811155f7 src/pt-stmt.cc --- 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 (expr); - if (expr->is_identifier ()) - { - tree_identifier *id = dynamic_cast (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 (); diff -r 93826ba0d078 -r 78f3811155f7 src/sighandlers.cc --- 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, diff -r 93826ba0d078 -r 78f3811155f7 src/toplev.cc --- 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 (); } diff -r 93826ba0d078 -r 78f3811155f7 src/utils.cc --- 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