changeset 18203:adbbacce8aaf

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.
author John W. Eaton <jwe@octave.org>
date Fri, 03 Jan 2014 14:34:47 -0500
parents 5646f999245d
children b29beed0e98d
files libinterp/corefcn/load-path.cc libinterp/corefcn/load-save.cc
diffstat 2 files changed, 69 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- 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++)
--- 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;
             }
         }