# HG changeset patch # User jwe # Date 857537742 0 # Node ID ef422e6f613898f727571e522acb208ef667a5c1 # Parent ecc1a12678de67ba08883c3b7cad82ef2e7e4914 [project @ 1997-03-05 04:53:36 by jwe] diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,18 @@ Tue Mar 4 20:36:53 1997 John W. Eaton + * 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. diff --git a/src/parse.y b/src/parse.y --- a/src/parse.y +++ b/src/parse.y @@ -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); diff --git a/src/pt-fcn.cc b/src/pt-fcn.cc --- a/src/pt-fcn.cc +++ b/src/pt-fcn.cc @@ -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 (); diff --git a/src/pt-fcn.h b/src/pt-fcn.h --- a/src/pt-fcn.h +++ b/src/pt-fcn.h @@ -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; } }; diff --git a/src/symtab.cc b/src/symtab.cc --- a/src/symtab.cc +++ b/src/symtab.cc @@ -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; diff --git a/src/symtab.h b/src/symtab.h --- a/src/symtab.h +++ b/src/symtab.h @@ -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);