# HG changeset patch # User Jaroslav Hajek # Date 1245821492 -7200 # Node ID 67ad3b58b99a20736f526e13118c026f11191717 # Parent 00b55509f5b59d83de167154221808289b16e087 improve error handling diff -r 00b55509f5b5 -r 67ad3b58b99a src/ChangeLog --- a/src/ChangeLog Wed Jun 24 07:30:49 2009 +0200 +++ b/src/ChangeLog Wed Jun 24 07:31:32 2009 +0200 @@ -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 -r 00b55509f5b5 -r 67ad3b58b99a src/octave.cc --- a/src/octave.cc Wed Jun 24 07:30:49 2009 +0200 +++ b/src/octave.cc Wed Jun 24 07:31:32 2009 +0200 @@ -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) { diff -r 00b55509f5b5 -r 67ad3b58b99a src/pt-eval.cc --- a/src/pt-eval.cc Wed Jun 24 07:30:49 2009 +0200 +++ b/src/pt-eval.cc Wed Jun 24 07:31:32 2009 +0200 @@ -909,6 +909,9 @@ { tree_statement_list *list = static_cast (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 diff -r 00b55509f5b5 -r 67ad3b58b99a src/toplev.cc --- a/src/toplev.cc Wed Jun 24 07:30:49 2009 +0200 +++ b/src/toplev.cc Wed Jun 24 07:31:32 2009 +0200 @@ -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 (); } diff -r 00b55509f5b5 -r 67ad3b58b99a src/toplev.h --- a/src/toplev.h Wed Jun 24 07:30:49 2009 +0200 +++ b/src/toplev.h Wed Jun 24 07:31:32 2009 +0200 @@ -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);