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 ();
 	}
     }