Mercurial > hg > octave-terminal
changeset 2985:aa9d0c0e0458
[project @ 1997-05-16 06:54:18 by jwe]
author | jwe |
---|---|
date | Fri, 16 May 1997 06:55:52 +0000 |
parents | 84c33881d0bc |
children | 35b3211c6ff9 |
files | src/ChangeLog src/DLD-FUNCTIONS/rand.cc src/dirfns.cc src/help.cc src/load-save.cc src/oct-hist.cc src/octave.cc src/ov-list.cc src/ov-struct.cc src/ov-usr-fcn.cc src/pager.cc src/pt-assign.cc src/pt-except.cc src/pt-jump.cc src/pt-jump.h src/pt-loop.cc src/pt-stmt.cc src/toplev.cc src/unwind-prot.cc src/unwind-prot.h src/utils.cc src/variables.cc |
diffstat | 22 files changed, 334 insertions(+), 286 deletions(-) [+] |
line wrap: on
line diff
--- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,12 @@ Fri May 16 00:07:11 1997 John W. Eaton <jwe@bevo.che.wisc.edu> + * unwind-prot.h, unwind-prot.cc: Make a bit more object-oriented. + Change all uses of unwind_protect stuff to match. + + * pt-jump.h, pt-jump.cc (breaking, continuing, returning): + Make these flags static members of the corresponding class. + Change all uses. + * pt-assign.cc (tree_simple_assignment_expression::eval, tree_multi_assignment_expression::eval): Clear lvalue index here.
--- a/src/DLD-FUNCTIONS/rand.cc +++ b/src/DLD-FUNCTIONS/rand.cc @@ -381,14 +381,14 @@ if (! initialized) do_initialization (); - begin_unwind_frame ("randn"); + unwind_protect::begin_frame ("randn"); // This relies on the fact that elements are popped from the // unwind stack in the reverse of the order they are pushed // (i.e. current_distribution will be reset before calling // reset_rand_generator()). - add_unwind_protect (reset_rand_generator, 0); + unwind_protect::add (reset_rand_generator, 0); unwind_protect_int (current_distribution); current_distribution = normal_dist; @@ -397,7 +397,7 @@ retval = do_rand (args, nargin); - run_unwind_frame ("randn"); + unwind_protect::run_frame ("randn"); } return retval;
--- a/src/dirfns.cc +++ b/src/dirfns.cc @@ -154,7 +154,7 @@ delete [] ls_command; - add_unwind_protect (cleanup_iprocstream, cmd); + unwind_protect::add (cleanup_iprocstream, cmd); if (cmd && *cmd) { @@ -165,7 +165,7 @@ else error ("couldn't start process for ls!"); - run_unwind_protect (); + unwind_protect::run (); return retval; }
--- a/src/help.cc +++ b/src/help.cc @@ -730,7 +730,7 @@ { octave_value_list retval; - begin_unwind_frame ("Ftype"); + unwind_protect::begin_frame ("Ftype"); int argc = args.length () + 1;
--- a/src/load-save.cc +++ b/src/load-save.cc @@ -1967,12 +1967,12 @@ } else if (tc.is_string ()) { - begin_unwind_frame ("save_mat_binary_data"); + unwind_protect::begin_frame ("save_mat_binary_data"); unwind_protect_int (Vimplicit_str_to_num_ok); Vimplicit_str_to_num_ok = 1; Matrix m = tc.matrix_value (); os.write (m.data (), 8 * len); - run_unwind_frame ("save_mat_binary_data"); + unwind_protect::run_frame ("save_mat_binary_data"); } else if (tc.is_range ()) {
--- a/src/oct-hist.cc +++ b/src/oct-hist.cc @@ -473,7 +473,7 @@ // Turn on command echo, so the output from this will make better // sense. - begin_unwind_frame ("do_edit_history"); + unwind_protect::begin_frame ("do_edit_history"); unwind_protect_int (Vecho_executing_commands); unwind_protect_int (input_from_tmp_history_file); Vecho_executing_commands = ECHO_CMD_LINE; @@ -481,7 +481,7 @@ parse_and_execute (name); - run_unwind_frame ("do_edit_history"); + unwind_protect::run_frame ("do_edit_history"); // Delete the temporary file. Should probably be done with an // unwind_protect. @@ -500,7 +500,7 @@ // Turn on command echo so the output from this will make better // sense. - begin_unwind_frame ("do_run_history"); + unwind_protect::begin_frame ("do_run_history"); unwind_protect_int (Vecho_executing_commands); unwind_protect_int (input_from_tmp_history_file); Vecho_executing_commands = ECHO_CMD_LINE; @@ -508,7 +508,7 @@ parse_and_execute (name); - run_unwind_frame ("do_run_history"); + unwind_protect::run_frame ("do_run_history"); // Delete the temporary file.
--- a/src/octave.cc +++ b/src/octave.cc @@ -215,7 +215,7 @@ static void execute_startup_files (void) { - begin_unwind_frame ("execute_startup_files"); + unwind_protect::begin_frame ("execute_startup_files"); // XXX FIXME XXX -- need to make it possible to set this in startup // files. @@ -277,7 +277,7 @@ parse_and_execute (local_rc, verbose); } - run_unwind_frame ("execute_startup_files"); + unwind_protect::run_frame ("execute_startup_files"); } // Usage message with extra help.
--- a/src/ov-list.cc +++ b/src/ov-list.cc @@ -89,7 +89,7 @@ void octave_list::print_raw (ostream& os, bool) const { - begin_unwind_frame ("octave_list_print"); + unwind_protect::begin_frame ("octave_list_print"); indent (os); os << "("; @@ -118,7 +118,7 @@ os << ")"; newline (os); - run_unwind_frame ("octave_list_print"); + unwind_protect::run_frame ("octave_list_print"); } bool
--- a/src/ov-struct.cc +++ b/src/ov-struct.cc @@ -87,7 +87,7 @@ // standard order. Maybe all substructures first, maybe // alphabetize entries, etc. - begin_unwind_frame ("octave_struct_print"); + unwind_protect::begin_frame ("octave_struct_print"); unwind_protect_int (Vstruct_levels_to_print); @@ -119,7 +119,7 @@ newline (os); } - run_unwind_frame ("octave_struct_print"); + unwind_protect::run_frame ("octave_struct_print"); } bool
--- a/src/ov-usr-fcn.cc +++ b/src/ov-usr-fcn.cc @@ -39,6 +39,7 @@ #include "ov-usr-fcn.h" #include "ov.h" #include "pager.h" +#include "pt-jump.h" #include "pt-misc.h" #include "pt-pr-code.h" #include "pt-stmt.h" @@ -57,12 +58,6 @@ // don't actually define any return variables. static bool Vreturn_last_computed_value; -// Nonzero means we're breaking out of a loop or function body. -extern int breaking; - -// Nonzero means we're returning from a function. -extern int returning; - // User defined functions. octave_allocator @@ -247,7 +242,7 @@ int nargin = args.length (); - begin_unwind_frame ("func_eval"); + unwind_protect::begin_frame ("func_eval"); unwind_protect_int (call_depth); call_depth++; @@ -255,13 +250,13 @@ if (symtab_entry && ! symtab_entry->is_read_only ()) { symtab_entry->protect (); - add_unwind_protect (unprotect_function, symtab_entry); + unwind_protect::add (unprotect_function, symtab_entry); } if (call_depth > 1) { sym_tab->push_context (); - add_unwind_protect (pop_symbol_table_context, sym_tab); + unwind_protect::add (pop_symbol_table_context, sym_tab); if (vr_list) { @@ -273,7 +268,7 @@ // Clear and delete the new one before restoring the old // one. - add_unwind_protect (delete_vr_list, vr_list); + unwind_protect::add (delete_vr_list, vr_list); } } @@ -282,7 +277,7 @@ // Force symbols to be undefined again when this function exits. - add_unwind_protect (clear_symbol_table, sym_tab); + unwind_protect::add (clear_symbol_table, sym_tab); // Save old and set current symbol table context, for // eval_undefined_error(). @@ -345,11 +340,11 @@ if (echo_commands) print_code_function_trailer (); - if (returning) - returning = 0; + if (tree_return_command::returning) + tree_return_command::returning = 0; - if (breaking) - breaking--; + if (tree_break_command::breaking) + tree_break_command::breaking--; if (error_state) { @@ -366,7 +361,7 @@ } abort: - run_unwind_frame ("func_eval"); + unwind_protect::run_frame ("func_eval"); return retval; }
--- a/src/pager.cc +++ b/src/pager.cc @@ -305,7 +305,7 @@ { if (! flushing_output_to_pager) { - begin_unwind_frame ("flush_octave_stdout"); + unwind_protect::begin_frame ("flush_octave_stdout"); unwind_protect_int (really_flush_to_pager); unwind_protect_int (flushing_output_to_pager); @@ -318,7 +318,7 @@ if (external_pager) clear_external_pager (); - run_unwind_frame ("flush_octave_stdout"); + unwind_protect::run_frame ("flush_octave_stdout"); } }
--- a/src/pt-assign.cc +++ b/src/pt-assign.cc @@ -44,12 +44,6 @@ #include "pt-walk.h" #include "utils.h" -// Nonzero means we're returning from a function. -extern int returning; - -// Nonzero means we're breaking out of a loop or function body. -extern int breaking; - // TRUE means print the right hand side of an assignment instead of // the left. static bool Vprint_rhs_assign_val;
--- a/src/pt-except.cc +++ b/src/pt-except.cc @@ -28,22 +28,13 @@ #include <config.h> #endif -// Nonzero means we're breaking out of a loop or function body. -extern int breaking; - -// Nonzero means we're jumping to the end of a loop. -extern int continuing; - -// Nonzero means we're returning from a function. Global because it -// is also needed in tree-expr.cc. -extern int returning; - #include "error.h" #include "oct-lvalue.h" #include "ov.h" #include "pt-cmd.h" #include "pt-except.h" #include "pt-exp.h" +#include "pt-jump.h" #include "pt-stmt.h" #include "pt-walk.h" #include "unwind-prot.h" @@ -67,18 +58,18 @@ buffer_error_messages = 0; bind_global_error_variable (); - add_unwind_protect (clear_global_error_variable, 0); + unwind_protect::add (clear_global_error_variable, 0); // Similarly, if we have seen a return or break statement, allow all // the catch code to run before returning or handling the break. // We don't have to worry about continue statements because they can // only occur in loops. - unwind_protect_int (returning); - returning = 0; + unwind_protect_int (tree_return_command::returning); + tree_return_command::returning = 0; - unwind_protect_int (breaking); - breaking = 0; + unwind_protect_int (tree_break_command::breaking); + tree_break_command::breaking = 0; if (list) list->eval (); @@ -90,26 +81,26 @@ // a return, or just jump to the end of the try_catch block? // The following code makes it just jump to the end of the block. - run_unwind_protect (); - if (breaking) - breaking--; + unwind_protect::run (); + if (tree_break_command::breaking) + tree_break_command::breaking--; // This is the one for returning. - if (returning) - discard_unwind_protect (); + if (tree_return_command::returning) + unwind_protect::discard (); else - run_unwind_protect (); + unwind_protect::run (); - run_unwind_protect (); + unwind_protect::run (); } void tree_try_catch_command::eval (void) { - begin_unwind_frame ("tree_try_catch::eval"); + unwind_protect::begin_frame ("tree_try_catch::eval"); - add_unwind_protect (do_catch_code, catch_code); + unwind_protect::add (do_catch_code, catch_code); if (catch_code) { @@ -123,12 +114,12 @@ if (catch_code && error_state) { error_state = 0; - run_unwind_frame ("tree_try_catch::eval"); + unwind_protect::run_frame ("tree_try_catch::eval"); } else { error_state = 0; - discard_unwind_frame ("tree_try_catch::eval"); + unwind_protect::discard_frame ("tree_try_catch::eval"); } } @@ -164,11 +155,11 @@ // We don't have to worry about continue statements because they can // only occur in loops. - unwind_protect_int (returning); - returning = 0; + unwind_protect_int (tree_return_command::returning); + tree_return_command::returning = 0; - unwind_protect_int (breaking); - breaking = 0; + unwind_protect_int (tree_break_command::breaking); + tree_break_command::breaking = 0; if (list) list->eval (); @@ -180,36 +171,36 @@ // a return, or just jump to the end of the unwind_protect block? // The following code makes it just jump to the end of the block. - run_unwind_protect (); - if (breaking) - breaking--; + unwind_protect::run (); + if (tree_break_command::breaking) + tree_break_command::breaking--; // This is the one for returning. - if (returning) - discard_unwind_protect (); + if (tree_return_command::returning) + unwind_protect::discard (); else - run_unwind_protect (); + unwind_protect::run (); // We don't want to ignore errors that occur in the cleanup code, so // if an error is encountered there, leave error_state alone. // Otherwise, set it back to what it was before. if (error_state) - discard_unwind_protect (); + unwind_protect::discard (); else - run_unwind_protect (); + unwind_protect::run (); } void tree_unwind_protect_command::eval (void) { - add_unwind_protect (do_unwind_protect_cleanup_code, cleanup_code); + unwind_protect::add (do_unwind_protect_cleanup_code, cleanup_code); if (unwind_protect_code) unwind_protect_code->eval (); - run_unwind_protect (); + unwind_protect::run (); } void
--- a/src/pt-jump.cc +++ b/src/pt-jump.cc @@ -28,22 +28,15 @@ #include <config.h> #endif -// Nonzero means we're breaking out of a loop or function body. -int breaking = 0; - -// Nonzero means we're jumping to the end of a loop. -int continuing = 0; - -// Nonzero means we're returning from a function. Global because it -// is also needed in tree-expr.cc. -int returning = 0; - #include "error.h" #include "pt-jump.h" #include "pt-walk.h" // Break. +// Nonzero means we're breaking out of a loop or function body. +int tree_break_command::breaking = 0; + void tree_break_command::eval (void) { @@ -59,6 +52,9 @@ // Continue. +// Nonzero means we're jumping to the end of a loop. +int tree_continue_command::continuing = 0; + void tree_continue_command::eval (void) { @@ -74,6 +70,10 @@ // Return. +// Nonzero means we're returning from a function. Global because it +// is also needed in tree-expr.cc. +int tree_return_command::returning = 0; + void tree_return_command::eval (void) {
--- a/src/pt-jump.h +++ b/src/pt-jump.h @@ -46,6 +46,8 @@ void eval (void); void accept (tree_walker& tw); + + static int breaking; }; // Continue. @@ -63,6 +65,8 @@ void eval (void); void accept (tree_walker& tw); + + static int continuing; }; // Return. @@ -80,6 +84,8 @@ void eval (void); void accept (tree_walker& tw); + + static int returning; }; #endif
--- a/src/pt-loop.cc +++ b/src/pt-loop.cc @@ -28,16 +28,6 @@ #include <config.h> #endif -// Nonzero means we're breaking out of a loop or function body. -extern int breaking; - -// Nonzero means we're jumping to the end of a loop. -extern int continuing; - -// Nonzero means we're returning from a function. Global because it -// is also needed in tree-expr.cc. -extern int returning; - #include "error.h" #include "gripes.h" #include "oct-map.h" @@ -46,6 +36,7 @@ #include "pt-arg-list.h" #include "pt-cmd.h" #include "pt-exp.h" +#include "pt-jump.h" #include "pt-loop.h" #include "pt-stmt.h" #include "pt-walk.h" @@ -56,13 +47,16 @@ { // Maybe handle `continue N' someday... - if (continuing) - continuing--; + if (tree_continue_command::continuing) + tree_continue_command::continuing--; - bool quit = (error_state || returning || breaking || continuing); + bool quit = (error_state + || tree_return_command::returning + || tree_break_command::breaking + || tree_continue_command::continuing); - if (breaking) - breaking--; + if (tree_break_command::breaking) + tree_break_command::breaking--; return quit; }
--- a/src/pt-stmt.cc +++ b/src/pt-stmt.cc @@ -39,21 +39,13 @@ #include "pt-cmd.h" #include "pt-id.h" #include "pt-idx.h" +#include "pt-jump.h" #include "pt-pr-code.h" #include "pt-stmt.h" #include "pt-walk.h" #include "utils.h" #include "variables.h" -// Nonzero means we're breaking out of a loop or function body. -extern int breaking; - -// Nonzero means we're jumping to the end of a loop. -extern int continuing; - -// Nonzero means we're returning from a function. -extern int returning; - // If TRUE, turn off printing of results in functions (as if a // semicolon has been appended to each statement). static bool Vsilent_functions; @@ -166,10 +158,11 @@ if (error_state) break; - if (breaking || continuing) + if (tree_break_command::breaking + || tree_continue_command::continuing) break; - if (returning) + if (tree_return_command::returning) break; } else
--- a/src/toplev.cc +++ b/src/toplev.cc @@ -67,6 +67,7 @@ #include "pathsearch.h" #include "procstream.h" #include "ov.h" +#include "pt-jump.h" #include "pt-plot.h" #include "pt-stmt.h" #include "sighandlers.h" @@ -81,12 +82,6 @@ // Nonzero means we print static bool Vdefault_eval_print_flag = true; -// Nonzero means we're breaking out of a loop or function body. -extern int breaking; - -// Nonzero means we're returning from a function. -extern int returning; - // Nonzero means we are using readline. // (--no-line-editing) int line_editing = 1; @@ -116,13 +111,13 @@ void parse_and_execute (FILE *f) { - begin_unwind_frame ("parse_and_execute"); + unwind_protect::begin_frame ("parse_and_execute"); YY_BUFFER_STATE old_buf = current_buffer (); YY_BUFFER_STATE new_buf = create_buffer (f); - add_unwind_protect (restore_input_buffer, old_buf); - add_unwind_protect (delete_input_buffer, new_buf); + unwind_protect::add (restore_input_buffer, old_buf); + unwind_protect::add (delete_input_buffer, new_buf); switch_to_buffer (new_buf); @@ -149,13 +144,14 @@ global_command = 0; - bool quit = (returning || breaking); + bool quit = (tree_return_command::returning + || tree_break_command::breaking); - if (returning) - returning = 0; + if (tree_return_command::returning) + tree_return_command::returning = 0; - if (breaking) - breaking--; + if (tree_break_command::breaking) + tree_break_command::breaking--; if (error_state) { @@ -171,7 +167,7 @@ } while (retval == 0); - run_unwind_frame ("parse_and_execute"); + unwind_protect::run_frame ("parse_and_execute"); } static void @@ -184,7 +180,7 @@ void parse_and_execute (const string& s, bool verbose, const char *warn_for) { - begin_unwind_frame ("parse_and_execute_2"); + unwind_protect::begin_frame ("parse_and_execute_2"); unwind_protect_int (reading_script_file); unwind_protect_str (curr_fcn_file_full_name); @@ -196,7 +192,7 @@ if (f) { - add_unwind_protect (safe_fclose, f); + unwind_protect::add (safe_fclose, f); unwind_protect_int (input_line_number); unwind_protect_int (current_input_column); @@ -219,7 +215,7 @@ else if (warn_for) error ("%s: unable to open file `%s'", warn_for, s.c_str ()); - run_unwind_frame ("parse_and_execute_2"); + unwind_protect::run_frame ("parse_and_execute_2"); } int @@ -263,13 +259,14 @@ if (! (interactive || forced_interactive)) { - bool quit = (returning || breaking); + bool quit = (tree_return_command::returning + || tree_break_command::breaking); - if (returning) - returning = 0; + if (tree_return_command::returning) + tree_return_command::returning = 0; - if (breaking) - breaking--; + if (tree_break_command::breaking) + tree_break_command::breaking--; if (quit) break; @@ -514,7 +511,7 @@ static octave_value_list eval_string (const string& s, bool silent, int& parse_status, int nargout) { - begin_unwind_frame ("eval_string"); + unwind_protect::begin_frame ("eval_string"); unwind_protect_int (get_input_from_eval_string); unwind_protect_int (input_from_command_line_file); @@ -528,8 +525,8 @@ YY_BUFFER_STATE old_buf = current_buffer (); YY_BUFFER_STATE new_buf = create_buffer (0); - add_unwind_protect (restore_input_buffer, old_buf); - add_unwind_protect (delete_input_buffer, new_buf); + unwind_protect::add (restore_input_buffer, old_buf); + unwind_protect::add (delete_input_buffer, new_buf); switch_to_buffer (new_buf); @@ -545,7 +542,7 @@ tree_statement_list *command = global_command; - run_unwind_frame ("eval_string"); + unwind_protect::run_frame ("eval_string"); octave_value_list retval; @@ -597,7 +594,7 @@ if (nargin > 0) { - begin_unwind_frame ("Feval"); + unwind_protect::begin_frame ("Feval"); if (nargin > 1) { @@ -619,14 +616,14 @@ buffer_error_messages = 0; bind_global_error_variable (); - add_unwind_protect (clear_global_error_variable, 0); + unwind_protect::add (clear_global_error_variable, 0); eval_string (args(1), 0, parse_status, nargout); retval = octave_value_list (); } - run_unwind_frame ("Feval"); + unwind_protect::run_frame ("Feval"); } else print_usage ("eval"); @@ -649,7 +646,7 @@ iprocstream *cmd = new iprocstream (cmd_str.c_str ()); - add_unwind_protect (cleanup_iprocstream, cmd); + unwind_protect::add (cleanup_iprocstream, cmd); int status = 127; @@ -682,7 +679,7 @@ else error ("unable to start subprocess for `%s'", cmd_str.c_str ()); - run_unwind_protect (); + unwind_protect::run (); return retval; }
--- a/src/unwind-prot.cc +++ b/src/unwind-prot.cc @@ -40,106 +40,43 @@ #include "unwind-prot.h" #include "utils.h" -// XXX FIXME XXX -- this should really be static, but that causes -// problems on some systems. -SLStack <unwind_elem> unwind_protect_list; - -void -add_unwind_protect (cleanup_func fptr, void *ptr) -{ - unwind_elem el (fptr, ptr); - unwind_protect_list.push (el); -} - -void -run_unwind_protect (void) -{ - unwind_elem el = unwind_protect_list.pop (); - - cleanup_func f = el.fptr (); - - if (f) - f (el.ptr ()); -} +SLStack<unwind_elem> unwind_protect::list; -void -discard_unwind_protect (void) -{ - unwind_protect_list.pop (); -} - -void -begin_unwind_frame (const string& tag) +class +saved_variable { - unwind_elem elem (tag); - unwind_protect_list.push (elem); -} - -void -run_unwind_frame (const string& tag) -{ - while (! unwind_protect_list.empty ()) - { - unwind_elem el = unwind_protect_list.pop (); - - cleanup_func f = el.fptr (); +public: - if (f) - f (el.ptr ()); - - if (tag == el.tag ()) - break; - } -} - -void -discard_unwind_frame (const string& tag) -{ - while (! unwind_protect_list.empty ()) - { - unwind_elem el = unwind_protect_list.pop (); - - if (tag == el.tag ()) - break; - } -} - -void -run_all_unwind_protects (void) -{ - while (! unwind_protect_list.empty ()) - { - unwind_elem el = unwind_protect_list.pop (); - - cleanup_func f = el.fptr (); - - if (f) - f (el.ptr ()); - } -} - -void -discard_all_unwind_protects (void) -{ - unwind_protect_list.clear (); -} - -class saved_variable -{ - public: - enum var_type { integer, string_type, generic_ptr, generic }; + enum var_type + { + boolean, + integer, + string_type, + generic_ptr, + generic + }; saved_variable (void); + + saved_variable (bool *p, bool v); + saved_variable (int *p, int v); + saved_variable (string *p, const string& v); + saved_variable (void **p, void *v); + ~saved_variable (void); void restore_value (void); - private: + static void restore (void *s); + +private: + union { + bool *ptr_to_bool; int *ptr_to_int; void *gen_ptr; void **ptr_to_gen_ptr; @@ -147,12 +84,14 @@ union { + bool bool_value; int int_value; const string *str_value; void *gen_ptr_value; }; var_type type_tag; + size_t size; }; @@ -164,6 +103,14 @@ size = 0; } +saved_variable::saved_variable (bool *p, bool v) +{ + type_tag = integer; + ptr_to_bool = p; + bool_value = v; + size = sizeof (bool); // Is this necessary? +} + saved_variable::saved_variable (int *p, int v) { type_tag = integer; @@ -210,6 +157,10 @@ { switch (type_tag) { + case boolean: + *ptr_to_bool = bool_value; + break; + case integer: *ptr_to_int = int_value; break; @@ -232,8 +183,8 @@ } } -static void -restore_saved_variable (void *s) +void +saved_variable::restore (void *s) { saved_variable *sv = static_cast<saved_variable *> (s); sv->restore_value (); @@ -241,24 +192,111 @@ } void -unwind_protect_int_internal (int *ptr, int value) +unwind_protect::add (unwind_elem::cleanup_func fptr, void *ptr) +{ + unwind_elem el (fptr, ptr); + list.push (el); +} + +void +unwind_protect::run (void) +{ + unwind_elem el = list.pop (); + + unwind_elem::cleanup_func f = el.fptr (); + + if (f) + f (el.ptr ()); +} + +void +unwind_protect::discard (void) { - saved_variable *s = new saved_variable (ptr, value); - add_unwind_protect (restore_saved_variable, s); + list.pop (); +} + +void +unwind_protect::begin_frame (const string& tag) +{ + unwind_elem elem (tag); + list.push (elem); +} + +void +unwind_protect::run_frame (const string& tag) +{ + while (! list.empty ()) + { + unwind_elem el = list.pop (); + + unwind_elem::cleanup_func f = el.fptr (); + + if (f) + f (el.ptr ()); + + if (tag == el.tag ()) + break; + } } void -unwind_protect_str_internal (string *ptr, const string& value) +unwind_protect::discard_frame (const string& tag) { - saved_variable *s = new saved_variable (ptr, value); - add_unwind_protect (restore_saved_variable, s); + while (! list.empty ()) + { + unwind_elem el = list.pop (); + + if (tag == el.tag ()) + break; + } +} + +void +unwind_protect::run_all (void) +{ + while (! list.empty ()) + { + unwind_elem el = list.pop (); + + unwind_elem::cleanup_func f = el.fptr (); + + if (f) + f (el.ptr ()); + } } void -unwind_protect_ptr_internal (void **ptr, void *value) +unwind_protect::discard_all (void) +{ + list.clear (); +} + +void +unwind_protect::save_bool (bool *ptr, bool value) +{ + saved_variable *s = new saved_variable (ptr, value); + add (saved_variable::restore, s); +} + +void +unwind_protect::save_int (int *ptr, int value) { saved_variable *s = new saved_variable (ptr, value); - add_unwind_protect (restore_saved_variable, s); + add (saved_variable::restore, s); +} + +void +unwind_protect::save_str (string *ptr, const string& value) +{ + saved_variable *s = new saved_variable (ptr, value); + add (saved_variable::restore, s); +} + +void +unwind_protect::save_ptr (void **ptr, void *value) +{ + saved_variable *s = new saved_variable (ptr, value); + add (saved_variable::restore, s); } /*
--- a/src/unwind-prot.h +++ b/src/unwind-prot.h @@ -31,36 +31,15 @@ #include <string> -typedef void (*cleanup_func)(void *ptr); - -void add_unwind_protect (cleanup_func fptr, void *ptr); -void run_unwind_protect (void); -void discard_unwind_protect (void); -void begin_unwind_frame (const string& tag); -void run_unwind_frame (const string& tag); -void discard_unwind_frame (const string& tag); -void run_all_unwind_protects (void); -void discard_all_unwind_protects (void); - -void unwind_protect_int_internal (int *ptr, int value); -void unwind_protect_str_internal (string *ptr, const string& value); -void unwind_protect_ptr_internal (void **ptr, void *value); -void unwind_protect_var_internal (void *ptr, void *value, size_t size); - -#define unwind_protect_int(i) \ - unwind_protect_int_internal (&(i), (i)) - -#define unwind_protect_str(s) \ - unwind_protect_str_internal (&(s), (s)) - -#define unwind_protect_ptr(p) \ - unwind_protect_ptr_internal (static_cast<void **> (&(p)), \ - static_cast<void *> (p)) +#include <SLStack.h> class unwind_elem { - public: +public: + + typedef void (*cleanup_func) (void *ptr); + unwind_elem (void) : ue_tag (), ue_fptr (0), ue_ptr (0) { } @@ -90,12 +69,66 @@ void *ptr (void) { return ue_ptr; } - private: +private: + string ue_tag; + cleanup_func ue_fptr; + void *ue_ptr; }; +class +unwind_protect +{ +public: + + static void add (unwind_elem::cleanup_func fptr, void *ptr); + + static void run (void); + + static void discard (void); + + static void begin_frame (const string& tag); + + static void run_frame (const string& tag); + + static void discard_frame (const string& tag); + + static void run_all (void); + + static void discard_all (void); + + // Ways to save variables. + + static void save_bool (bool *ptr, bool value); + + static void save_int (int *ptr, int value); + + static void save_str (string *ptr, const string& value); + + static void save_ptr (void **ptr, void *value); + + static void save_var (void *ptr, void *value, size_t size); + + static SLStack<unwind_elem> list; +}; + +// We could get by without these macros, but they are nice to have... + +#define unwind_protect_bool(b) \ + unwind_protect::save_bool (&(b), (b)) + +#define unwind_protect_int(i) \ + unwind_protect::save_int (&(i), (i)) + +#define unwind_protect_str(s) \ + unwind_protect::save_str (&(s), (s)) + +#define unwind_protect_ptr(p) \ + unwind_protect::save_ptr (static_cast<void **> (&(p)), \ + static_cast<void *> (p)) + #endif /*
--- a/src/utils.cc +++ b/src/utils.cc @@ -88,7 +88,7 @@ extern "C" void jump_to_top_level (void) { - run_all_unwind_protects (); + unwind_protect::run_all (); longjmp (toplevel, 1); }
--- a/src/variables.cc +++ b/src/variables.cc @@ -746,7 +746,7 @@ static int parse_fcn_file (bool exec_script, const string& ff) { - begin_unwind_frame ("parse_fcn_file"); + unwind_protect::begin_frame ("parse_fcn_file"); int script_file_executed = 0; @@ -756,7 +756,7 @@ FILE *in_stream = command_editor::get_input_stream (); - add_unwind_protect (restore_input_stream, in_stream); + unwind_protect::add (restore_input_stream, in_stream); unwind_protect_ptr (ff_instream); @@ -772,7 +772,7 @@ FILE *ffile = get_input_from_file (ff, 0); - add_unwind_protect (safe_fclose, ffile); + unwind_protect::add (safe_fclose, ffile); if (ffile) { @@ -786,7 +786,7 @@ // Vsaving_history variable... command_history::ignore_entries (); - add_unwind_protect (restore_command_history, 0); + unwind_protect::add (restore_command_history, 0); unwind_protect_int (Vecho_executing_commands); unwind_protect_int (Vsaving_history); @@ -801,8 +801,8 @@ YY_BUFFER_STATE old_buf = current_buffer (); YY_BUFFER_STATE new_buf = create_buffer (ffile); - add_unwind_protect (restore_input_buffer, (void *) old_buf); - add_unwind_protect (delete_input_buffer, (void *) new_buf); + unwind_protect::add (restore_input_buffer, (void *) old_buf); + unwind_protect::add (delete_input_buffer, (void *) new_buf); switch_to_buffer (new_buf); @@ -835,7 +835,7 @@ // Vsaving_history variable... command_history::ignore_entries (); - add_unwind_protect (restore_command_history, 0); + unwind_protect::add (restore_command_history, 0); unwind_protect_int (Vsaving_history); unwind_protect_int (reading_script_file); @@ -849,7 +849,7 @@ } } - run_unwind_frame ("parse_fcn_file"); + unwind_protect::run_frame ("parse_fcn_file"); return script_file_executed; } @@ -871,7 +871,7 @@ // These are needed by yyparse. - begin_unwind_frame ("load_fcn_from_file"); + unwind_protect::begin_frame ("load_fcn_from_file"); unwind_protect_str (curr_fcn_file_name); unwind_protect_str (curr_fcn_file_full_name); @@ -885,7 +885,7 @@ if (! (error_state || script_file_executed)) force_link_to_function (nm); - run_unwind_frame ("load_fcn_from_file"); + unwind_protect::run_frame ("load_fcn_from_file"); } return script_file_executed; @@ -975,11 +975,11 @@ if (fptr) { - add_unwind_protect (safe_fclose, (void *) fptr); + unwind_protect::add (safe_fclose, (void *) fptr); retval = gobble_leading_white_space (fptr, true, true); - run_unwind_protect (); + unwind_protect::run (); } }