changeset 2791:ef422e6f6138

[project @ 1997-03-05 04:53:36 by jwe]
author jwe
date Wed, 05 Mar 1997 04:55:42 +0000
parents ecc1a12678de
children 32259460c627
files src/ChangeLog src/parse.y src/pt-fcn.cc src/pt-fcn.h src/symtab.cc src/symtab.h
diffstat 6 files changed, 62 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Wed Mar 05 02:47:55 1997 +0000
+++ b/src/ChangeLog	Wed Mar 05 04:55:42 1997 +0000
@@ -1,5 +1,18 @@
 Tue Mar  4 20:36:53 1997  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
+	* pt-fcn.cc (tree_function::eval): Protect function from being
+	redefined while it is being evaluated.
+	(unprotect_function): New function, for use with unwind_protect stuff.
+	* pt-fcn.h (tree_function::symtab_entry): New data member.
+	(tree_function::init): Initialize it to 0.
+	(tree_function::stash_symtab_ptr): New function.
+	* parse.y (frob_function_def): Stash pointer to function's
+	symbol_record in the function definition.
+
+	* symtab.cc (symbol_record::read_only_error): New argument,
+	action.  Change all callers.
+	(symbol_record::rename): Don't allow read-only symbols to be renamed.
+
 	* variables.cc (Fexist): Don't let files with `.' in their names
 	confuse us.
 
--- a/src/parse.y	Wed Mar 05 02:47:55 1997 +0000
+++ b/src/parse.y	Wed Mar 05 04:55:42 1997 +0000
@@ -2199,6 +2199,13 @@
 
   top_level_sym_tab->clear (id_name);
 
+  symbol_record *sr = global_sym_tab->lookup (id_name, 0, 0);
+
+  if (sr)
+    fcn->stash_symtab_ptr (sr);
+  else
+    panic_impossible ();
+
   id->define (fcn);
 
   id->document (help_buf);
--- a/src/pt-fcn.cc	Wed Mar 05 02:47:55 1997 +0000
+++ b/src/pt-fcn.cc	Wed Mar 05 04:55:42 1997 +0000
@@ -244,6 +244,13 @@
   tmp->clear ();
 }
 
+static void
+unprotect_function (void *sr_arg)
+{
+  symbol_record *sr = (symbol_record *) sr_arg;
+  sr->unprotect ();
+}
+
 octave_value_list
 tree_function::eval (bool /* print */, int nargout, const octave_value_list& args)
 {
@@ -262,6 +269,12 @@
   unwind_protect_int (call_depth);
   call_depth++;
 
+  if (symtab_entry && ! symtab_entry->is_read_only ())
+    {
+      symtab_entry->protect ();
+      add_unwind_protect (unprotect_function, (void *) symtab_entry);
+    }
+
   if (call_depth > 1)
     {
       sym_tab->push_context ();
--- a/src/pt-fcn.h	Wed Mar 05 02:47:55 1997 +0000
+++ b/src/pt-fcn.h	Wed Mar 05 04:55:42 1997 +0000
@@ -74,6 +74,9 @@
   void stash_fcn_file_time (time_t t)
     { t_parsed = t; }
 
+  void stash_symtab_ptr (symbol_record *sr)
+    { symtab_entry = sr; }
+
   string fcn_file_name (void)
     { return file_name; }
 
@@ -165,6 +168,9 @@
   // returned.
   tree_va_return_list *vr_list;
 
+  // The symbol record for this function.
+  symbol_record *symtab_entry;
+
   // The symbol record for nargin in the local symbol table.
   symbol_record *nargin_sr;
 
@@ -191,6 +197,7 @@
       num_args_passed = 0;
       curr_va_arg_number = 0;
       vr_list = 0;
+      symtab_entry = 0;
     }
 };
 
--- a/src/symtab.cc	Wed Mar 05 02:47:55 1997 +0000
+++ b/src/symtab.cc	Wed Mar 05 04:55:42 1997 +0000
@@ -266,7 +266,8 @@
 void
 symbol_record::rename (const string& new_name)
 {
-  nm = new_name;
+  if (! read_only_error ("rename"))
+    nm = new_name;
 }
 
 int
@@ -388,7 +389,7 @@
 int
 symbol_record::define (tree_constant *t)
 {
-  if (is_variable () && read_only_error ())
+  if (is_variable () && read_only_error ("redefine"))
     return 0;
 
   tree_fvc *saved_def = 0;
@@ -433,7 +434,7 @@
 int
 symbol_record::define (tree_builtin *t, int text_fcn)
 {
-  if (read_only_error ())
+  if (read_only_error ("redefine"))
     return 0;
 
   if (is_variable ())
@@ -462,7 +463,7 @@
 int
 symbol_record::define (tree_function *t, int text_fcn)
 {
-  if (read_only_error ())
+  if (read_only_error ("redefine"))
     return 0;
 
   if (is_variable ())
@@ -490,7 +491,7 @@
 int
 symbol_record::define_as_fcn (const octave_value& v)
 {
-  if (is_variable () && read_only_error ())
+  if (is_variable () && read_only_error ("redefine"))
     return 0;
 
   if (is_variable ())
@@ -682,21 +683,21 @@
 }
 
 int
-symbol_record::read_only_error (void)
+symbol_record::read_only_error (const char *action)
 {
   if (is_read_only ())
     {
       if (is_variable ())
 	{
-	  ::error ("can't redefine read-only constant `%s'", nm.c_str ());
+	  ::error ("can't %s read-only constant `%s'", action, nm.c_str ());
 	}
       else if (is_function ())
 	{
-	  ::error ("can't redefine read-only function `%s'", nm.c_str ());
+	  ::error ("can't %s read-only function `%s'", action, nm.c_str ());
 	}
       else
 	{
-	  ::error ("can't redefine read-only symbol `%s'", nm.c_str ());
+	  ::error ("can't %s read-only symbol `%s'", action, nm.c_str ());
 	}
 
       return 1;
@@ -914,13 +915,19 @@
     {
       if (ptr->name () == old_name)
 	{
-	  prev->chain (ptr->next ());
-
-	  index = hash (new_name) & HASH_MASK;
-	  table[index].chain (ptr);
 	  ptr->rename (new_name);
 
-	  return;
+	  if (! error_state)
+	    {
+	      prev->chain (ptr->next ());
+
+	      index = hash (new_name) & HASH_MASK;
+	      table[index].chain (ptr);
+
+	      return;
+	    }
+
+	  break;
 	}
 
       prev = ptr;
--- a/src/symtab.h	Wed Mar 05 02:47:55 1997 +0000
+++ b/src/symtab.h	Wed Mar 05 04:55:42 1997 +0000
@@ -207,7 +207,7 @@
 
   void init_state (void);
 
-  int read_only_error (void);
+  int read_only_error (const char *action);
 
   void push_def (symbol_def *sd);
   symbol_def *pop_def (void);