# HG changeset patch # User jwe # Date 775373747 0 # Node ID 94fd73d1a0bceb7de26f31097f47392f516f08fa # Parent 37082b93ec7efc73d6e37155a18843bc6b913e03 [project @ 1994-07-28 05:35:47 by jwe] diff --git a/src/help.cc b/src/help.cc --- a/src/help.cc +++ b/src/help.cc @@ -609,7 +609,7 @@ if (sym_rec) { tree_identifier tmp (sym_rec); - tmp.parse_fcn_file (0); + tmp.load_fcn_from_file (0); char *h = sym_rec->help (); if (h && *h) { diff --git a/src/parse.y b/src/parse.y --- a/src/parse.y +++ b/src/parse.y @@ -959,7 +959,9 @@ warning ("function name `%s' does not agree\ with function file name `%s.m'", id_name, curr_fcn_file_name); - $1->rename (curr_fcn_file_name); + global_sym_tab->rename (id_name, + curr_fcn_file_name); + id_name = $1->name (); } diff --git a/src/pt-exp-base.cc b/src/pt-exp-base.cc --- a/src/pt-exp-base.cc +++ b/src/pt-exp-base.cc @@ -746,12 +746,6 @@ return sym->name (); } -void -tree_identifier::rename (const char *n) -{ - sym->rename (n); -} - tree_identifier * tree_identifier::define (tree_constant *t) { @@ -875,20 +869,6 @@ } } -int -tree_identifier::parse_fcn_file (int exec_script) -{ - curr_fcn_file_name = name (); - char *ff = fcn_file_in_path (curr_fcn_file_name); - int script_file_executed = parse_fcn_file (ff, exec_script); - delete [] ff; - - if (! (error_state || script_file_executed)) - force_link_to_function (name ()); - - return script_file_executed; -} - static void gobble_leading_white_space (FILE *ffile) { @@ -938,101 +918,132 @@ } int -tree_identifier::parse_fcn_file (char *ff, int exec_script) +tree_identifier::load_fcn_from_file (int exec_script) +{ + int script_file_executed = 0; + + curr_fcn_file_name = name (); + + char *oct_file = oct_file_in_path (curr_fcn_file_name); + + int loaded_oct_file = 0; + + if (oct_file) + { + cerr << "found: " << oct_file << "\n"; + + delete [] oct_file; + +// XXX FIXME XXX -- this is where we try to link to an external +// object... + loaded_oct_file = 1; + } + + if (! loaded_oct_file) + { + char *ff = fcn_file_in_path (curr_fcn_file_name); + + if (ff) + { + script_file_executed = parse_fcn_file (exec_script, ff); + delete [] ff; + } + + if (! (error_state || script_file_executed)) + { + char *foo = name (); + force_link_to_function (foo); + } + } + + return script_file_executed; +} + +int +tree_identifier::parse_fcn_file (int exec_script, char *ff) { begin_unwind_frame ("parse_fcn_file"); int script_file_executed = 0; - if (ff) - { + assert (ff); + // Open function file and parse. - int old_reading_fcn_file_state = reading_fcn_file; - - unwind_protect_ptr (rl_instream); - unwind_protect_ptr (ff_instream); - - unwind_protect_int (using_readline); - unwind_protect_int (input_line_number); - unwind_protect_int (current_input_column); - unwind_protect_int (reading_fcn_file); - - using_readline = 0; - reading_fcn_file = 1; - input_line_number = 0; - current_input_column = 1; - - FILE *ffile = get_input_from_file (ff, 0); - - if (ffile) - { + int old_reading_fcn_file_state = reading_fcn_file; + + unwind_protect_ptr (rl_instream); + unwind_protect_ptr (ff_instream); + + unwind_protect_int (using_readline); + unwind_protect_int (input_line_number); + unwind_protect_int (current_input_column); + unwind_protect_int (reading_fcn_file); + + using_readline = 0; + reading_fcn_file = 1; + input_line_number = 0; + current_input_column = 1; + + FILE *ffile = get_input_from_file (ff, 0); + + if (ffile) + { // Check to see if this file defines a function or is just a list of // commands. - if (is_function_file (ffile)) + if (is_function_file (ffile)) + { + unwind_protect_int (echo_input); + unwind_protect_int (saving_history); + unwind_protect_int (reading_fcn_file); + + echo_input = 0; + saving_history = 0; + reading_fcn_file = 1; + + 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); + + switch_to_buffer (new_buf); + + unwind_protect_ptr (curr_sym_tab); + + reset_parser (); + + int status = yyparse (); + + if (status != 0) { - parse_fcn_file (ffile, ff); + ::error ("parse error while reading function file %s", ff); + global_sym_tab->clear (curr_fcn_file_name); } - else if (exec_script) - { + } + else if (exec_script) + { // The value of `reading_fcn_file' will be restored to the proper value // when we unwind from this frame. - reading_fcn_file = old_reading_fcn_file_state; - - unwind_protect_int (reading_script_file); - reading_script_file = 1; - - parse_and_execute (ffile, 1); - - script_file_executed = 1; - } - fclose (ffile); + reading_fcn_file = old_reading_fcn_file_state; + + unwind_protect_int (reading_script_file); + reading_script_file = 1; + + parse_and_execute (ffile, 1); + + script_file_executed = 1; } - - run_unwind_frame ("parse_fcn_file"); + fclose (ffile); } + run_unwind_frame ("parse_fcn_file"); + return script_file_executed; } void -tree_identifier::parse_fcn_file (FILE *ffile, char *ff) -{ - begin_unwind_frame ("parse_fcn_file_2"); - - unwind_protect_int (echo_input); - unwind_protect_int (saving_history); - unwind_protect_int (reading_fcn_file); - - echo_input = 0; - saving_history = 0; - reading_fcn_file = 1; - - 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); - - switch_to_buffer (new_buf); - - unwind_protect_ptr (curr_sym_tab); - - reset_parser (); - - int status = yyparse (); - - if (status != 0) - { - ::error ("parse error while reading function file %s", ff); - global_sym_tab->clear (curr_fcn_file_name); - } - - run_unwind_frame ("parse_fcn_file_2"); -} - -void tree_identifier::eval_undefined_error (void) { char *nm = sym->name (); @@ -1048,7 +1059,7 @@ * Try to find a definition for an identifier. Here's how: * * * If the identifier is already defined and is a function defined - * in an function file that has been modified since the last time + * in an function file that has been modified since the last time * we parsed it, parse it again. * * * If the identifier is not defined, try to find a builtin @@ -1056,6 +1067,9 @@ * * * If the identifier is still undefined, try looking for an * function file to parse. + * + * * On systems that support dynamic linking, we prefer .oct files + * over .m files. */ tree_fvc * tree_identifier::do_lookup (int& script_file_executed) @@ -1068,7 +1082,7 @@ { if (sym->is_function () && symbol_out_of_date (sym)) { - script_file_executed = parse_fcn_file (); + script_file_executed = load_fcn_from_file (); } } else if (! sym->is_formal_parameter ()) @@ -1077,11 +1091,11 @@ if (! sym->is_defined ()) { - script_file_executed = parse_fcn_file (); + script_file_executed = load_fcn_from_file (); } else if (sym->is_function () && symbol_out_of_date (sym)) { - script_file_executed = parse_fcn_file (); + script_file_executed = load_fcn_from_file (); } } } diff --git a/src/pt-exp-base.h b/src/pt-exp-base.h --- a/src/pt-exp-base.h +++ b/src/pt-exp-base.h @@ -427,7 +427,6 @@ int is_identifier (void) const; char *name (void) const; - void rename (const char *n); tree_identifier *define (tree_constant *t); tree_identifier *define (tree_function *t); @@ -441,9 +440,9 @@ void bump_value (tree::expression_type); - int parse_fcn_file (int exec_script = 1); - int parse_fcn_file (char *ff, int exec_script = 1); - void parse_fcn_file (FILE *ffile, char *ff); + int load_fcn_from_file (int exec_script = 1); + + int parse_fcn_file (int exec_script = 1, char *ff = 0); tree_fvc *do_lookup (int& script_file_executed); diff --git a/src/symtab.cc b/src/symtab.cc --- a/src/symtab.cc +++ b/src/symtab.cc @@ -257,19 +257,19 @@ return definition ? definition->help () : 0; } -void -symbol_record::rename (const char *n) -{ - delete [] nm; - nm = strsave (n); -} - tree_fvc * symbol_record::def (void) const { return definition ? definition->def () : 0; } +void +symbol_record::rename (const char *new_name) +{ + delete [] nm; + nm = strsave (new_name); +} + int symbol_record::is_function (void) const { @@ -919,6 +919,34 @@ } void +symbol_table::rename (const char *old_name, const char *new_name) +{ + int index = hash (old_name) & HASH_MASK; + + symbol_record *prev = &table[index]; + symbol_record *ptr = prev->next (); + + while (ptr) + { + if (strcmp (ptr->name (), old_name) == 0) + { + prev->chain (ptr->next ()); + + index = hash (new_name) & HASH_MASK; + table[index].chain (ptr); + ptr->rename (new_name); + + return; + } + + prev = ptr; + ptr = ptr->next (); + } + + panic_impossible (); +} + +void symbol_table::clear (int clear_user_functions) { for (int i = 0; i < HASH_TABLE_SIZE; i++) diff --git a/src/symtab.h b/src/symtab.h --- a/src/symtab.h +++ b/src/symtab.h @@ -136,7 +136,7 @@ char *help (void) const; tree_fvc *def (void) const; - void rename (const char *n); + void rename (const char *new_name); int is_function (void) const; int is_user_function (void) const; @@ -299,6 +299,8 @@ symbol_record *lookup (const char *nm, int insert = 0, int warn = 0); + void rename (const char *old_name, const char *new_name); + void clear (int clear_user_functions = 1); int clear (const char *nm, int clear_user_functions = 1); diff --git a/src/utils.cc b/src/utils.cc --- a/src/utils.cc +++ b/src/utils.cc @@ -598,6 +598,16 @@ } /* + * See if there is an octave file in the path. If so, return the + * full path to the file. + */ +char * +oct_file_in_path (const char *name) +{ + return file_in_path (name, ".oct"); +} + +/* ;;; Local Variables: *** ;;; mode: C++ *** ;;; page-delimiter: "^/\\*" *** diff --git a/src/utils.h b/src/utils.h --- a/src/utils.h +++ b/src/utils.h @@ -41,6 +41,7 @@ extern void discard_until (istream&, char); extern char *file_in_path (const char *, const char *); extern char *fcn_file_in_path (const char *); +extern char *oct_file_in_path (const char *); extern char **pathstring_to_vector (char *pathstring); extern void jump_to_top_level (void); extern int almost_match (const char *std, const char *s, diff --git a/src/variables.cc b/src/variables.cc --- a/src/variables.cc +++ b/src/variables.cc @@ -677,13 +677,13 @@ if (sr && symbol_out_of_date (sr)) { tree_identifier tmp (sr); - tmp.parse_fcn_file (0); + tmp.load_fcn_from_file (0); } else { sr = global_sym_tab->lookup (fcn_name, 1, 0); tree_identifier tmp (sr); - tmp.parse_fcn_file (0); + tmp.load_fcn_from_file (0); } ans = sr->def ();