Mercurial > hg > octave-nkf
changeset 6323:ea65de49e18e
[project @ 2007-02-17 02:51:02 by jwe]
author | jwe |
---|---|
date | Sat, 17 Feb 2007 02:51:03 +0000 |
parents | 723a32c8ee10 |
children | d5904124b917 |
files | liboctave/ChangeLog liboctave/oct-shlib.h scripts/ChangeLog scripts/miscellaneous/Makefile.in src/ChangeLog src/defun-int.h src/defun.cc src/dirfns.cc src/dirfns.h src/dynamic-ld.cc src/dynamic-ld.h src/ov-fcn-handle.cc src/ov-fcn.h src/ov-usr-fcn.cc src/ov-usr-fcn.h src/parse.y src/utils.cc src/utils.h src/variables.cc src/variables.h |
diffstat | 20 files changed, 320 insertions(+), 103 deletions(-) [+] |
line wrap: on
line diff
--- a/liboctave/ChangeLog +++ b/liboctave/ChangeLog @@ -1,3 +1,9 @@ +2007-02-16 John W. Eaton <jwe@octave.org> + + * oct-shlib.h (octave_shlib::relative): New data member. + (octave_shlib::mark_relative, octave_shlib::is_relative): + New functions. + 2007-02-16 Michael Goffioul <michael.goffioul@swing.be> * lo-sysdep.cc (octave_popen2): New function to simulate popen2 on
--- a/liboctave/oct-shlib.h +++ b/liboctave/oct-shlib.h @@ -50,9 +50,10 @@ typedef void (*close_hook) (const std::string&); - octave_shlib (void) : rep (make_shlib ()) { } + octave_shlib (void) : relative (false), rep (make_shlib ()) { } - octave_shlib (const std::string& f) : rep (make_shlib ()) { open (f); } + octave_shlib (const std::string& f) + : relative (false), rep (make_shlib ()) { open (f); } virtual ~octave_shlib (void) { @@ -102,6 +103,10 @@ virtual bool is_out_of_date (void) const { return rep->is_out_of_date (); } + void mark_relative (void) { relative = true; } + + bool is_relative (void) const { return relative; } + virtual int number_of_functions_loaded (void) const { return rep->number_of_functions_loaded (); } @@ -119,6 +124,9 @@ static octave_shlib *make_shlib (void); + // TRUE if this function was found from a relative path element. + bool relative; + union { octave_shlib *rep;
--- a/scripts/ChangeLog +++ b/scripts/ChangeLog @@ -1,3 +1,7 @@ +2007-02-16 John W. Eaton <jwe@octave.org> + + * miscellaneous/Makefile.in (SOURCES): Remove popen2.m from the list. + 2007-02-16 Michael Goffioul <michael.goffioul@swing.be> * miscellaneous/popen2.m: Remove as replaced with builtin.
--- a/scripts/miscellaneous/Makefile.in +++ b/scripts/miscellaneous/Makefile.in @@ -27,7 +27,7 @@ inputname.m ispc.m isunix.m license.m list_primes.m ls.m \ ls_command.m menu.m mex.m mexext.m mkoctfile.m movefile.m \ news.m not.m orderfields.m pack.m paren.m parseparams.m \ - popen2.m semicolon.m setfield.m single.m substruct.m tar.m \ + semicolon.m setfield.m single.m substruct.m tar.m \ tempdir.m tempname.m texas_lotto.m unix.m unpack.m untar.m \ unzip.m ver.m version.m warning_ids.m xor.m zip.m
--- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,15 +1,86 @@ +2007-02-16 John W. Eaton <jwe@octave.org> + + * dynamic-ld.cc (octave_dynamic_loader::do_load_oct): Clear + function if original was loaded from relative path and the name + can no longer be found in path. Mark files found from relative + path as relative. + (clear): Only warn if there is more than one function to clear. + + * variables.cc (symbol_out_of_date): Don't ignore return value in + call to octave_env::make_absolute. + (symbol_out_of_date): Clear symbol if original was loaded from + relative path and name can no longer be found in path. + + * dynamic-ld.cc (octave_dynamic_loader::do_load_oct): + Also check whether new file is same as the old file. + + * utils.cc (same_file): Move here from variables.cc. + * utils.h: (same_file): Provide decl. + + * parse.y (frob_function): Stash parent function name if parsing + nested function. + + * ov-fcn-handle.cc (make_fcn_handle): Pass current function name + as parent in call to lookup_function. + + * ov-fcn.h (octave_function::parent_fcn_name): New virtual function. + + * ov-usr-fcn.h (octave_user_function::parent_name): New data member. + (octave_user_function::stash_parent_function_name, + octave_user_function::parent_function_name): New methods. + * ov-usr-fcn.cc (octave_user_function::octave_user_function): + Initialize parent_name. + + * variables.h, variables.cc (lookup_function): New arg, parent. + If not empty, try this first for lookup. + + * dynamic-ld.cc (octave_dynamic_loader::do_load_mex): If doing + path lookup, check relative status. Pass relative to oct_file_in_path. + (octave_dynamic_loader::do_load_mex): Likewise, for mex_file_in_path + + * defun-int.h, defun.cc (install_mex_function): New arg, relative. + (install_dld_function): Likewise. + (octave_dld_fcn_installer): Likewise. + (DEFINE_FUNX_INSTALLER_FUN3): Pass relative to install_dld_function. + + * dynamic-ld.h (octave_dynamic_loader::load_oct, + octave_dynamic_loader::load_mex, + octave_dynamic_loader::do_load_oct + octave_dynamic_loader::do_load_mex): New arg, relative. + + * dirfns.h (Vcurrent_directory): Delete unused variable. + + * variables.cc (symbol_out_of_date): Also compare function time + stamp to Vlast_chdir_time if function is from relative lookup. + + * dirfns.cc (Vlast_chdir_time): New variable. + (octave_change_to_directory): Update it if chdir succeeds. + * dirfns.h (Vlast_chdir_time): Provide decl. + + * ov-fcn.h (octave_function::relative): New data member. + (octave_function::mark_relative, octave_function::is_relative): + New functions. + + * parse.y (fcn_file_from_relative_lookup): New static variable. + (load_fcn_from_file): Note whether function file was found from + relative path element. + (frob_function): Maybe mark function as relative. + + * parse.y (lookup_autoload): Don't call octave_env::make_absolute + on return value. + * variables.cc (symbol_out_of_date): Make name absolute after call + to lookup_autoload. + + * input.cc (interactive_input): New arg, DEBUG. Don't call + drawnow if debugging. + (get_user_input): Pass DEBUG to interactive_input. + 2007-02-16 Michael Goffioul <michael.goffioul@swing.be> * syscalls.cc (Fpopen2): New function. (pipe): Modify to return input and output file descriptor seperately rather than in a list. -2007-02-16 John W. Eaton <jwe@octave.org> - - * input.cc (interactive_input): New arg, DEBUG. Don't call - drawnow if debugging. - (get_user_input): Pass DEBUG to interactive_input. - 2007-02-16 Muthiah Annamalai <muthuspost@gmail.com> * debug.cc (Fdbtype): Improve compatibility.
--- a/src/defun-int.h +++ b/src/defun-int.h @@ -50,11 +50,13 @@ extern OCTINTERP_API void install_dld_function (octave_dld_function::fcn f, const std::string& name, const octave_shlib& shl, - const std::string& doc, bool is_text_fcn = false); + const std::string& doc, bool is_text_fcn = false, + bool relative = false); extern OCTINTERP_API void install_mex_function (void *fptr, bool fmex, const std::string& name, - const octave_shlib& shl, bool is_text_fcn = false); + const octave_shlib& shl, bool is_text_fcn = false, + bool relative = false); extern OCTINTERP_API void alias_builtin (const std::string& alias, const std::string& name); @@ -70,7 +72,7 @@ // the symbol table. We look for this name instead of the actual // function so that we can easily install the doc std::string too. -typedef bool (*octave_dld_fcn_installer) (const octave_shlib&); +typedef bool (*octave_dld_fcn_installer) (const octave_shlib&, bool relative); #define DEFINE_FUN_INSTALLER_FUN(name, doc) \ DEFINE_FUN_INSTALLER_FUN2(name, doc, CXX_ABI) @@ -91,10 +93,10 @@ extern "C" \ OCTAVE_EXPORT \ bool \ - fsname ## _ ## cxx_abi (const octave_shlib& shl) \ + fsname ## _ ## cxx_abi (const octave_shlib& shl, bool relative) \ { \ check_version (OCTAVE_API_VERSION, name); \ - install_dld_function (fname, name, shl, doc); \ + install_dld_function (fname, name, shl, doc, false, relative); \ return error_state ? false : true; \ }
--- a/src/defun.cc +++ b/src/defun.cc @@ -165,7 +165,8 @@ void install_dld_function (octave_dld_function::fcn f, const std::string& name, const octave_shlib& shl, - const std::string& doc, bool is_text_fcn) + const std::string& doc, bool is_text_fcn, + bool relative) { symbol_record *sym_rec = fbi_sym_tab->lookup (name, true); @@ -175,7 +176,13 @@ t |= symbol_record::COMMAND; sym_rec->unprotect (); - sym_rec->define (new octave_dld_function (f, shl, name, doc), t); + + octave_dld_function *df = new octave_dld_function (f, shl, name, doc); + + if (relative) + df->mark_relative (); + + sym_rec->define (df, t); sym_rec->document (doc); // Also insert the full name in the symbol table. This way, we can @@ -189,7 +196,8 @@ void install_mex_function (void *fptr, bool fmex, const std::string& name, - const octave_shlib& shl, bool is_text_fcn) + const octave_shlib& shl, bool is_text_fcn, + bool relative) { symbol_record *sym_rec = fbi_sym_tab->lookup (name, true); @@ -199,7 +207,13 @@ t |= symbol_record::COMMAND; sym_rec->unprotect (); - sym_rec->define (new octave_mex_function (fptr, fmex, shl, name), t); + + octave_mex_function *mf = new octave_mex_function (fptr, fmex, shl, name); + + if (relative) + mf->mark_relative (); + + sym_rec->define (mf, t); // Also insert the full name in the symbol table. This way, we can // properly cope with changes to LOAD_PATH.
--- a/src/dirfns.cc +++ b/src/dirfns.cc @@ -69,6 +69,9 @@ // directory tree. static bool Vconfirm_recursive_rmdir = true; +// The time we last time we changed directories. +octave_time Vlast_chdir_time = 0.0; + static int octave_change_to_directory (const std::string& newdir) { @@ -76,6 +79,8 @@ if (cd_ok) { + Vlast_chdir_time.stamp (); + // FIXME -- should this be handled as a list of functions // to call so users can add their own chdir handlers?
--- a/src/dirfns.h +++ b/src/dirfns.h @@ -28,12 +28,15 @@ #include <string> +#include "oct-time.h" + extern std::string polite_directory_format (const std::string&); extern std::string base_pathname (const std::string&); extern std::string make_absolute (const std::string&, const std::string&); extern std::string get_working_directory (const std::string&); -extern std::string Vcurrent_directory; +// The time we last time we changed directories. +extern octave_time Vlast_chdir_time; #endif
--- a/src/dynamic-ld.cc +++ b/src/dynamic-ld.cc @@ -27,6 +27,7 @@ #include <list> +#include "oct-env.h" #include "oct-time.h" #include "file-stat.h" @@ -302,9 +303,21 @@ fbi_sym_tab->clear (fcn_name); } +static void +clear (octave_shlib& oct_file) +{ + if (oct_file.number_of_functions_loaded () > 1) + warning_with_id ("Octave:reload-forces-clear", + "reloading %s clears the following functions:", + oct_file.file_name().c_str ()); + + octave_shlib_list::remove (oct_file, do_clear_function); +} + bool octave_dynamic_loader::do_load_oct (const std::string& fcn_name, - const std::string& file_name) + const std::string& file_name, + bool relative) { bool retval = false; @@ -321,26 +334,37 @@ if (! error_state) { - if (function && oct_file.is_out_of_date ()) + if (function + && (! same_file (file_name, oct_file.file_name ()) + || oct_file.is_out_of_date ())) { - int n = oct_file.number_of_functions_loaded (); - - if (n > 0) - warning_with_id ("Octave:reload-forces-clear", - "reloading %s clears the following functions:", - oct_file.file_name().c_str ()); - - octave_shlib_list::remove (oct_file, do_clear_function); - + clear (oct_file); function = 0; } if (! function) { - std::string oct_file_name - = file_name.empty () ? oct_file_in_path (fcn_name) : file_name; + std::string oct_file_name = file_name; + + if (oct_file_name.empty ()) + { + oct_file_name = oct_file_in_path (fcn_name); + + if (! oct_file_name.empty ()) + relative = ! octave_env::absolute_pathname (oct_file_name); + } - if (! oct_file_name.empty ()) + if (oct_file_name.empty ()) + { + if (oct_file.is_relative ()) + { + // Can't see this function from current + // directory, so we should clear it. + clear (oct_file); + function = 0; + } + } + else { oct_file.open (oct_file_name); @@ -348,6 +372,9 @@ { if (oct_file) { + if (relative) + oct_file.mark_relative (); + octave_shlib_list::append (oct_file); function = oct_file.search (fcn_name, mangle_name); @@ -357,7 +384,6 @@ oct_file_name.c_str ()); } } - } } @@ -366,7 +392,7 @@ octave_dld_fcn_installer f = FCN_PTR_CAST (octave_dld_fcn_installer, function); - retval = f (oct_file); + retval = f (oct_file, relative); if (! retval) ::error ("failed to install .oct file function `%s'", @@ -380,7 +406,8 @@ bool octave_dynamic_loader::do_load_mex (const std::string& fcn_name, - const std::string& file_name) + const std::string& file_name, + bool relative) { bool retval = false; @@ -392,8 +419,15 @@ doing_load = true; - std::string mex_file_name - = file_name.empty () ? mex_file_in_path (fcn_name) : file_name; + std::string mex_file_name = file_name; + + if (mex_file_name.empty ()) + { + mex_file_name = mex_file_in_path (fcn_name); + + if (! mex_file_name.empty ()) + relative = ! octave_env::absolute_pathname (mex_file_name); + } void *function = 0; @@ -434,7 +468,7 @@ if (function) { - install_mex_function (function, have_fmex, fcn_name, mex_file); + install_mex_function (function, have_fmex, fcn_name, mex_file, relative); retval = true; } @@ -467,16 +501,20 @@ bool octave_dynamic_loader::load_oct (const std::string& fcn_name, - const std::string& file_name) + const std::string& file_name, + bool relative) { - return (instance_ok ()) ? instance->do_load_oct (fcn_name, file_name) : false; + return (instance_ok ()) + ? instance->do_load_oct (fcn_name, file_name, relative) : false; } bool octave_dynamic_loader::load_mex (const std::string& fcn_name, - const std::string& file_name) + const std::string& file_name, + bool relative) { - return (instance_ok ()) ? instance->do_load_mex (fcn_name, file_name) : false; + return (instance_ok ()) + ? instance->do_load_mex (fcn_name, file_name, relative) : false; } bool
--- a/src/dynamic-ld.h +++ b/src/dynamic-ld.h @@ -40,10 +40,12 @@ virtual ~octave_dynamic_loader (void) { } static bool load_oct (const std::string& fcn_name, - const std::string& file_name = std::string ()); + const std::string& file_name = std::string (), + bool relative = false); static bool load_mex (const std::string& fcn_name, - const std::string& file_name = std::string ()); + const std::string& file_name = std::string (), + bool relative = false); static bool remove (const std::string& fcn_name, octave_shlib& shl); @@ -60,10 +62,12 @@ static bool instance_ok (void); bool do_load_oct (const std::string& fcn_name, - const std::string& file_name = std::string ()); + const std::string& file_name = std::string (), + bool relative = false); bool do_load_mex (const std::string& fcn_name, - const std::string& file_name = std::string ()); + const std::string& file_name = std::string (), + bool relative = false); bool do_remove (const std::string& fcn_name, octave_shlib& shl);
--- a/src/ov-fcn-handle.cc +++ b/src/ov-fcn-handle.cc @@ -612,7 +612,9 @@ { octave_value retval; - octave_value f = lookup_function (nm); + octave_function *fcn = octave_call_stack::current (); + + octave_value f = lookup_function (nm, fcn->name ()); if (f.is_function ()) retval = octave_value (new octave_fcn_handle (f, nm));
--- a/src/ov-fcn.h +++ b/src/ov-fcn.h @@ -61,6 +61,8 @@ virtual std::string fcn_file_name (void) const { return std::string (); } + virtual std::string parent_fcn_name (void) const { return std::string (); } + virtual void mark_fcn_file_up_to_date (const octave_time&) { } virtual octave_time time_parsed (void) const @@ -79,6 +81,10 @@ virtual bool takes_var_return (void) const { return false; } + void mark_relative (void) { relative = true; } + + bool is_relative (void) const { return relative; } + std::string name (void) const { return my_name; } void document (const std::string& ds) { doc = ds; } @@ -93,7 +99,10 @@ octave_function (const std::string& nm, const std::string& ds = std::string ()) - : my_name (nm), doc (ds) { } + : relative (false), my_name (nm), doc (ds) { } + + // TRUE if this function was found from a relative path element. + bool relative; // The name of this function. std::string my_name;
--- a/src/ov-usr-fcn.cc +++ b/src/ov-usr-fcn.cc @@ -74,7 +74,7 @@ : octave_function (std::string (), std::string ()), param_list (pl), ret_list (rl), cmd_list (cl), sym_tab (st), lead_comm (), trail_comm (), file_name (), - t_parsed (static_cast<time_t> (0)), + parent_name (), t_parsed (static_cast<time_t> (0)), t_checked (static_cast<time_t> (0)), system_fcn_file (false), call_depth (0), num_named_args (0), nested_function (false), inline_function (false), args_passed (),
--- a/src/ov-usr-fcn.h +++ b/src/ov-usr-fcn.h @@ -108,6 +108,8 @@ void stash_fcn_file_name (const std::string& nm); + void stash_parent_fcn_name (const std::string& p) { parent_name = p; } + void stash_leading_comment (octave_comment_list *lc) { lead_comm = lc; } void stash_trailing_comment (octave_comment_list *tc) { trail_comm = tc; } @@ -124,6 +126,8 @@ std::string fcn_file_name (void) const { return file_name; } + std::string parent_fcn_name (void) const { return parent_name; } + octave_time time_parsed (void) const { return t_parsed; } octave_time time_checked (void) const { return t_checked; } @@ -220,9 +224,12 @@ // The comments preceding the ENDFUNCTION token. octave_comment_list *trail_comm; - // The name of the file we parsed + // The name of the file we parsed. std::string file_name; + // The name of the parent function, if any. + std::string parent_name; + // The time the file was parsed. octave_time t_parsed;
--- a/src/parse.y +++ b/src/parse.y @@ -118,6 +118,10 @@ // TRUE means we are in the process of autoloading a function. static bool autoloading = false; +// TRUE means the current function file was found in a relative path +// element. +static bool fcn_file_from_relative_lookup = false; + // List of autoloads (function -> file mapping). static std::map<std::string, std::string> autoload_map; @@ -2483,6 +2487,12 @@ fcn->stash_fcn_file_time (now); fcn->mark_as_system_fcn_file (); + if (fcn_file_from_relative_lookup) + fcn->mark_relative (); + + if (lexer_flags.parsing_nested_function) + fcn->stash_parent_fcn_name (parent_function_name); + std::string nm = fcn->fcn_file_name (); file_stat fs (nm); @@ -3229,7 +3239,8 @@ } static bool -parse_fcn_file (const std::string& ff, bool exec_script, bool force_script = false) +parse_fcn_file (const std::string& ff, bool exec_script, + bool force_script = false) { unwind_protect::begin_frame ("parse_fcn_file"); @@ -3366,8 +3377,7 @@ am_iter p = autoload_map.find (nm); if (p != autoload_map.end ()) - retval = octave_env::make_absolute (load_path::find_file (p->second), - octave_env::getcwd ()); + retval = load_path::find_file (p->second); return retval; } @@ -3411,6 +3421,10 @@ std::string file; + unwind_protect_bool (fcn_file_from_relative_lookup); + + fcn_file_from_relative_lookup = false; + if (octave_env::absolute_pathname (nm) && ((nm_len > 4 && nm.substr (nm_len-4) == ".oct") || (nm_len > 4 && nm.substr (nm_len-4) == ".mex") @@ -3433,20 +3447,23 @@ exec_script = true; } else - file = octave_env::make_absolute - (load_path::find_fcn (nm), octave_env::getcwd ()); + file = load_path::find_fcn (nm); + + fcn_file_from_relative_lookup = ! octave_env::absolute_pathname (file); + + file = octave_env::make_absolute (file, octave_env::getcwd ()); } int len = file.length (); if (len > 4 && file.substr (len-4, len-1) == ".oct") { - if (octave_dynamic_loader::load_oct (nm, file)) + if (octave_dynamic_loader::load_oct (nm, file, fcn_file_from_relative_lookup)) force_link_to_function (nm); } else if (len > 4 && file.substr (len-4, len-1) == ".mex") { - if (octave_dynamic_loader::load_mex (nm, file)) + if (octave_dynamic_loader::load_mex (nm, file, fcn_file_from_relative_lookup)) force_link_to_function (nm); } else if (len > 2)
--- a/src/utils.cc +++ b/src/utils.cc @@ -113,6 +113,20 @@ return retval; } +// Return TRUE if F and G are both names for the same file. + +bool +same_file (const std::string& f, const std::string& g) +{ + std::string c_f = file_ops::canonicalize_file_name (f); + std::string c_g = file_ops::canonicalize_file_name (g); + + file_stat f_fs (c_f); + file_stat g_fs (c_g); + + return (f_fs.ino () == g_fs.ino () && f_fs.dev () == g_fs.dev ()); +} + int almost_match (const std::string& std, const std::string& s, int min_match_len, int case_sens)
--- a/src/utils.h +++ b/src/utils.h @@ -39,15 +39,21 @@ extern OCTINTERP_API bool valid_identifier (const char *s); extern OCTINTERP_API bool valid_identifier (const std::string& s); -extern OCTINTERP_API int almost_match (const std::string& std, const std::string& s, - int min_match_len = 1, int case_sens = 1); +extern OCTINTERP_API bool +same_file (const std::string& f, const std::string& g); + +extern OCTINTERP_API int almost_match (const std::string& std, + const std::string& s, + int min_match_len = 1, + int case_sens = 1); extern OCTINTERP_API int keyword_almost_match (const char * const *std, int *min_len, const std::string& s, int min_toks_to_match, int max_toks); -extern OCTINTERP_API int empty_arg (const char *name, octave_idx_type nr, octave_idx_type nc); +extern OCTINTERP_API int empty_arg (const char *name, octave_idx_type nr, + octave_idx_type nc); extern OCTINTERP_API std::string search_path_for_file (const std::string&, const string_vector&); @@ -55,7 +61,9 @@ extern OCTINTERP_API string_vector search_path_for_all_files (const std::string&, const string_vector&); -extern OCTINTERP_API std::string file_in_path (const std::string&, const std::string&); +extern OCTINTERP_API std::string +file_in_path (const std::string&, const std::string&); + extern OCTINTERP_API std::string fcn_file_in_path (const std::string&); extern OCTINTERP_API std::string oct_file_in_path (const std::string&); extern OCTINTERP_API std::string mex_file_in_path (const std::string&); @@ -75,13 +83,15 @@ extern OCTINTERP_API void get_dimensions (const octave_value& a, const octave_value& b, - const char *warn_for, octave_idx_type& nr, octave_idx_type& nc); + const char *warn_for, octave_idx_type& nr, + octave_idx_type& nc); extern OCTINTERP_API void -get_dimensions (const octave_value& a, - const char *warn_for, octave_idx_type& nr, octave_idx_type& nc); +get_dimensions (const octave_value& a,const char *warn_for, + octave_idx_type& nr, octave_idx_type& nc); -extern OCTINTERP_API Matrix identity_matrix (octave_idx_type nr, octave_idx_type nc); +extern OCTINTERP_API Matrix +identity_matrix (octave_idx_type nr, octave_idx_type nc); extern OCTINTERP_API int octave_format (std::ostream& os, const char *fmt, ...); @@ -99,8 +109,8 @@ extern "C" OCTINTERP_API void octave_usleep (unsigned int useconds); -extern "C" OCTINTERP_API int octave_raw_vsnprintf (char *buf, size_t n, const char *fmt, - va_list args); +extern "C" OCTINTERP_API int +octave_raw_vsnprintf (char *buf, size_t n, const char *fmt, va_list args); #endif
--- a/src/variables.cc +++ b/src/variables.cc @@ -962,20 +962,6 @@ return retval; } -// Return TRUE if F and G are both names for the same file. - -static bool -same_file (const std::string& f, const std::string& g) -{ - std::string c_f = file_ops::canonicalize_file_name (f); - std::string c_g = file_ops::canonicalize_file_name (g); - - file_stat f_fs (c_f); - file_stat g_fs (c_g); - - return (f_fs.ino () == g_fs.ino () && f_fs.dev () == g_fs.dev ()); -} - bool fcn_out_of_date (octave_function *fcn, const std::string& ff, time_t tp) { @@ -1020,7 +1006,12 @@ if (! ff.empty ()) { - if (fcn->time_checked () < Vlast_prompt_time) + octave_time tc = fcn->time_checked (); + + bool relative = fcn->is_relative (); + + if (tc < Vlast_prompt_time + || (relative && tc < Vlast_chdir_time)) { time_t tp = fcn->time_parsed (); @@ -1047,19 +1038,27 @@ file = lookup_autoload (nm); if (file.empty ()) - { - file = octave_env::make_absolute - (load_path::find_fcn (nm), octave_env::getcwd ()); - } + file = load_path::find_fcn (nm); + + file = octave_env::make_absolute (file, octave_env::getcwd ()); } - if (same_file (file, ff)) + if (relative && file.empty ()) + { + // Can't see this function from current + // directory, so we should clear it. + + sr->clear (); + + retval = true; + } + else if (same_file (file, ff)) { retval = fcn_out_of_date (fcn, ff, tp); } else { - // Check the full function name. Maybe we alrady + // Check the full function name. Maybe we already // parsed it. symbol_record *full_sr = fbi_sym_tab->lookup (file); @@ -1147,18 +1146,17 @@ } octave_value -lookup_function (const std::string& nm) +lookup_function (const std::string& nm, const std::string& parent) { octave_value retval; symbol_record *sr = 0; - if (curr_parent_function) - { - std::string parent = curr_parent_function->name (); - - sr = fbi_sym_tab->lookup (parent + ":" + nm); - } + if (! parent.empty ()) + sr = fbi_sym_tab->lookup (parent + ":" + nm); + + if (! sr || ! sr->is_function () && curr_parent_function) + sr = fbi_sym_tab->lookup (curr_parent_function->name () + ":" + nm); if (! sr || ! sr->is_function ()) { @@ -1464,12 +1462,15 @@ symbol_record *tmp_sym = 0; - if (curr_parent_function) - { - std::string parent = curr_parent_function->name (); - - tmp_sym = fbi_sym_tab->lookup (parent + ":" + nm); - } + octave_function *fcn = octave_call_stack::current (); + + std::string parent = fcn ? fcn->parent_fcn_name () : std::string (); + + if (! parent.empty ()) + tmp_sym = fbi_sym_tab->lookup (parent + ":" + nm); + + if (! tmp_sym && curr_parent_function) + tmp_sym = fbi_sym_tab->lookup (curr_parent_function->name () + ":" + nm); if (! tmp_sym) tmp_sym = fbi_sym_tab->lookup (nm);
--- a/src/variables.h +++ b/src/variables.h @@ -99,7 +99,9 @@ extern OCTINTERP_API symbol_record * lookup_by_name (const std::string& nm, bool exec_script = true); -extern OCTINTERP_API octave_value lookup_function (const std::string& nm); +extern OCTINTERP_API octave_value +lookup_function (const std::string& nm, + const std::string& parent = std::string ()); extern OCTINTERP_API octave_value lookup_user_function (const std::string& nm);