# HG changeset patch # User Jaroslav Hajek # Date 1245764920 -7200 # Node ID d57f0c56195f265b719d959deb8bb749077668d8 # Parent ab563d2adc10e3c98609f55c65475dfdb5845e9d improve error handling diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,15 @@ +2009-06-23 Jaroslav Hajek + + * 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 * oct-map.cc (Octave_map::squeeze, Octave_map::permute, diff --git a/src/octave.cc b/src/octave.cc --- a/src/octave.cc +++ b/src/octave.cc @@ -398,15 +398,12 @@ { eval_string (code, false, parse_status, 0); } - catch (octave_quit_exception e) - { - unwind_protect::run_frame (uwp_frame); - 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) { @@ -470,15 +467,12 @@ source_file (fname, context, verbose, require_file, "octave"); } - catch (octave_quit_exception e) - { - unwind_protect::run_frame (uwp_frame); - 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) { diff --git a/src/pt-eval.cc b/src/pt-eval.cc --- a/src/pt-eval.cc +++ b/src/pt-eval.cc @@ -903,6 +903,9 @@ { tree_statement_list *list = static_cast (ptr); + unwind_protect::protect_var (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 @@ -911,9 +914,6 @@ unwind_protect::protect_var (error_state); error_state = 0; - unwind_protect::protect_var (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 diff --git a/src/toplev.cc b/src/toplev.cc --- 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 (uwp_frame); } - 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 (); } diff --git a/src/toplev.h b/src/toplev.h --- 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);