# HG changeset patch # User John W. Eaton # Date 1388777687 18000 # Node ID adbbacce8aaf9da2e44809578387f21723c98052 # Parent 5646f999245de6f85b544734fa861e042296ba80 find load file in private directories (bug #35697) * load-path.cc (find_private_file): New static function. (load_path::do_find_file): Use it. * load-save.cc (find_file_to_load): Include file name in warning. diff -r 5646f999245d -r adbbacce8aaf libinterp/corefcn/load-path.cc --- a/libinterp/corefcn/load-path.cc Fri Jan 03 10:52:41 2014 -0800 +++ b/libinterp/corefcn/load-path.cc Fri Jan 03 14:34:47 2014 -0500 @@ -38,6 +38,7 @@ #include "defun.h" #include "input.h" #include "load-path.h" +#include "ov-usr-fcn.h" #include "pager.h" #include "parse.h" #include "toplev.h" @@ -1253,38 +1254,80 @@ } } +// Should we cache all files in private directories, or is it OK to just +// look them up each time as needed? + +std::string +find_private_file (const std::string& fname) +{ + std::string retval; + + // Look in private directory corresponding to current function (if + // any). + + octave_user_function *curr_fcn = symbol_table::get_curr_fcn (); + + if (curr_fcn && ! curr_fcn->is_private_function ()) + { + std::string dir_name = curr_fcn->dir_name (); + + if (! dir_name.empty ()) + { + std::string pfname = dir_name + file_ops::dir_sep_str () + + "private" + file_ops::dir_sep_str () + fname; + + file_stat fs (pfname); + + if (fs.exists () && fs.is_reg ()) + retval = pfname; + } + } + + return retval; +} + std::string load_path::do_find_file (const std::string& file) const { std::string retval; + if (octave_env::absolute_pathname (file) + || octave_env::rooted_relative_pathname (file)) + { + file_stat fs (file); + + if (fs.exists ()) + return file; + } + else + { + std::string tfile = find_private_file (file); + + if (! tfile.empty ()) + return tfile; + } + if (file.find_first_of (file_ops::dir_sep_chars ()) != std::string::npos) { - if (octave_env::absolute_pathname (file) - || octave_env::rooted_relative_pathname (file)) + // Given name has a directory separator, so append it to each + // element of the load path in turn. + + for (const_dir_info_list_iterator p = dir_info_list.begin (); + p != dir_info_list.end (); + p++) { - file_stat fs (file); + std::string tfile = file_ops::concat (p->dir_name, file); + + file_stat fs (tfile); if (fs.exists ()) - return file; - } - else - { - for (const_dir_info_list_iterator p = dir_info_list.begin (); - p != dir_info_list.end (); - p++) - { - std::string tfile = file_ops::concat (p->dir_name, file); - - file_stat fs (tfile); - - if (fs.exists ()) - return tfile; - } + return tfile; } } else { + // Look in cache. + for (const_dir_info_list_iterator p = dir_info_list.begin (); p != dir_info_list.end (); p++) diff -r 5646f999245d -r adbbacce8aaf libinterp/corefcn/load-save.cc --- a/libinterp/corefcn/load-save.cc Fri Jan 03 10:52:41 2014 -0800 +++ b/libinterp/corefcn/load-save.cc Fri Jan 03 14:34:47 2014 -0500 @@ -502,17 +502,24 @@ if (! (octave_env::absolute_pathname (fname) || octave_env::rooted_relative_pathname (fname))) { + // Load path will also search "." first, but we don't want to + // issue a warning if the file is found in the current directory, + // so do an explicit check for that. + file_stat fs (fname); if (! (fs.exists () && fs.is_reg ())) { + // Not directly found; search load path. + std::string tmp = octave_env::make_absolute (load_path::find_file (fname)); if (! tmp.empty ()) { warning_with_id ("Octave:load-file-in-path", - "load: file found in load path"); + "load: file found in load path: %s", + tmp.c_str ()); fname = tmp; } }