Mercurial > hg > octave-max
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 +++ b/libcruft/ChangeLog @@ -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 +++ b/libcruft/misc/cquit.c @@ -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 +++ b/libcruft/misc/f77-fcn.h @@ -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 +++ b/libcruft/misc/quit.cc @@ -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 +++ b/libcruft/misc/quit.h @@ -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 +++ b/src/ChangeLog @@ -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 +++ b/src/DLD-FUNCTIONS/urlwrite.cc @@ -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 +++ b/src/octave.cc @@ -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 +++ b/src/pt-stmt.cc @@ -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 +++ b/src/sighandlers.cc @@ -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,