octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

load function doesn't check path


From: John W. Eaton
Subject: load function doesn't check path
Date: Mon, 13 Nov 2006 21:54:53 -0500

On 13-Nov-2006, John W. Eaton wrote:

| On 13-Nov-2006, Frederick (Rick) A Niles wrote:
| 
| | I'm sure this is a FAQ, but it seems the "load" function in Octave 
| | doesn't check the "path" that's used for functions.
| | 
| | I've noticed a lot of MATLAB code that relies on this behavior.  Is this 
| | something that will change in the future?
| 
| In
| 
|    http://velveeta.che.wisc.edu/octave/lists/help-octave/2004/2134
| 
| I wrote:
| 
|   Yes, it is intentional, because it seemed to me that looking in the
|   LOADPATH for files to open could easily lead to a lot of confusion and
|   possibly bad science if you thought you were opening one file and
|   happened to find another somewhere on the path.
| 
|   Perhaps we should fix this for compatibility.  If we do, then I
|   propose that we have Octave issue a warning if the file is found on
|   the load path rather than by using the supplied name.
| 
|   If you must find data files on the load path with the current version
|   of Octave, you might try using the function
| 
|     file_in_loadpath
| 
|   to search for you before calling fopen.
| 
| 
| This message was about fopen, which also searches MATLABPATH in
| Matlab, but it also applies to load.
| 
| So, should we search the load path?  Is a warning acceptable if the
| file is not an absolute filename and it is also not found in the
| current directory?  I suppose the warning should be disabled at
| startup if --traditional is used.

OK, I just checked in the following changes.

jwe


ChangeLog:

2006-11-13  John W. Eaton  <address@hidden>

        * octave.cc (maximum_braindamage): Disable
        Octave:fopen-file-in-path and Octave:load-file-in-path warnings.


src/ChangeLog:

2006-11-13  John W. Eaton  <address@hidden>

        * load-save.cc (find_file_to_load): New function.
        (Fload): Call find_file_to_load to search load path for file.

        * file-io.cc (Ffopen): Search load path for file.

        * load-path.cc (path::do_find_first_of, path::do_find_file):
        Break out of all loops once file is found, not just innermost one.


Index: src/file-io.cc
===================================================================
RCS file: /cvs/octave/src/file-io.cc,v
retrieving revision 1.181
diff -u -u -r1.181 file-io.cc
--- src/file-io.cc      27 Oct 2006 01:45:56 -0000      1.181
+++ src/file-io.cc      14 Nov 2006 02:52:33 -0000
@@ -59,10 +59,13 @@
 
 #include "error.h"
 #include "file-ops.h"
+#include "file-stat.h"
 #include "lo-ieee.h"
+#include "oct-env.h"
 
 #include "defun.h"
 #include "file-io.h"
+#include "load-path.h"
 #include "oct-fstrm.h"
 #include "oct-iostrm.h"
 #include "oct-map.h"
@@ -391,6 +394,26 @@
 
       if (! error_state)
        {
+         std::string fname = file_ops::tilde_expand (name);
+
+         if (! (md & std::ios::out || octave_env::absolute_pathname (fname)))
+           {
+             file_stat fs (fname);
+
+             if (! fs.exists ())
+               {
+                 std::string tmp = octave_env::make_absolute
+                   (load_path::find_file (fname), octave_env::getcwd ());
+
+                 if (! tmp.empty ())
+                   {
+                     warning_with_id ("Octave:fopen-file-in-path",
+                                      "fopen: file found in load path");
+                     fname = tmp;
+                   }
+               }
+           }
+
 #if defined (HAVE_ZLIB)
          std::string tmode = mode;
 
@@ -400,10 +423,10 @@
            {
              tmode.erase (pos, 1);
 
-             gzFile fptr = ::gzopen (name.c_str (), tmode.c_str ());
+             gzFile fptr = ::gzopen (fname.c_str (), tmode.c_str ());
 
              if (fptr)
-               retval = octave_zstdiostream::create (name, fptr, md, flt_fmt);
+               retval = octave_zstdiostream::create (fname, fptr, md, flt_fmt);
              else
                {
                  using namespace std;
@@ -413,9 +436,9 @@
          else
 #endif
            {
-             FILE *fptr = ::fopen (name.c_str (), mode.c_str ());
+             FILE *fptr = ::fopen (fname.c_str (), mode.c_str ());
 
-             retval = octave_stdiostream::create (name, fptr, md, flt_fmt);
+             retval = octave_stdiostream::create (fname, fptr, md, flt_fmt);
 
              if (! fptr)
                {
Index: src/load-path.cc
===================================================================
RCS file: /cvs/octave/src/load-path.cc,v
retrieving revision 1.11
diff -u -u -r1.11 load-path.cc
--- src/load-path.cc    9 Nov 2006 18:26:56 -0000       1.11
+++ src/load-path.cc    14 Nov 2006 02:52:33 -0000
@@ -761,11 +761,14 @@
          if (all_files[i] == file)
            {
              dir_name = p->dir_name;
-             break;
+
+             goto done;
            }
        }
     }
 
+ done:
+
   if (! dir_name.empty ())
     retval = dir_name + file_ops::dir_sep_str + file;
 
@@ -810,19 +813,21 @@
 
       for (octave_idx_type i = 0; i < len; i++)
        {
-         
          for (octave_idx_type j = 0; j < rel_flen; j++)
            {
              if (all_files[i] == rel_flist[j])
                {
                  dir_name = p->dir_name;
                  file_name = rel_flist[j];
-                 break;
+
+                 goto done;
                }
            }
        }
     }
 
+ done:
+
   if (! dir_name.empty ())
     retval = dir_name + file_ops::dir_sep_str + file_name;
 
Index: src/load-save.cc
===================================================================
RCS file: /cvs/octave/src/load-save.cc,v
retrieving revision 1.218
diff -u -u -r1.218 load-save.cc
--- src/load-save.cc    30 Aug 2006 20:03:53 -0000      1.218
+++ src/load-save.cc    14 Nov 2006 02:52:33 -0000
@@ -46,6 +46,7 @@
 #include "byte-swap.h"
 #include "data-conv.h"
 #include "file-ops.h"
+#include "file-stat.h"
 #include "glob-match.h"
 #include "lo-mappers.h"
 #include "mach-info.h"
@@ -58,6 +59,7 @@
 #include "defun.h"
 #include "error.h"
 #include "gripes.h"
+#include "load-path.h"
 #include "load-save.h"
 #include "oct-obj.h"
 #include "oct-map.h"
@@ -586,6 +588,52 @@
   return retval;
 }
 
+std::string
+find_file_to_load (const std::string& name, const std::string& orig_name)
+{
+  std::string fname = name;
+
+  if (! octave_env::absolute_pathname (fname))
+    {
+      file_stat fs (fname);
+
+      if (! fs.exists ())
+       {
+         std::string tmp = octave_env::make_absolute
+           (load_path::find_file (fname), octave_env::getcwd ());
+
+         if (! tmp.empty ())
+           {
+             warning_with_id ("Octave:load-file-in-path",
+                              "load: file found in load path");
+             fname = tmp;
+           }
+       }
+    }
+
+  if (fname.rfind (".") == NPOS)
+    {
+      file_stat fs (fname);
+
+      if (! fs.exists ())
+       fname = find_file_to_load (fname + ".mat", orig_name);
+    }
+  else
+    {
+      file_stat fs (fname);
+  
+      if (! fs.exists ())
+       {
+         fname = "";
+
+         error ("load: unable to find file %s", orig_name.c_str ());
+       }
+    }
+
+  return fname;
+}
+
+
 // HDF5 load/save documentation is included in the Octave manual
 // regardless, but if HDF5 is not linked in we also include a
 // sentence noting this, so the user understands that the features
@@ -646,7 +694,7 @@
 @table @code\n\
 @item -force\n\
 The @samp{-force} option is accepted but ignored for backward\n\
-compatiability. Octave now overwrites variables currently in memory with\n\
+compatibility. Octave now overwrites variables currently in memory with\n\
 the same name as those found in the file.\n\
 \n\
 @item -ascii\n\
@@ -685,7 +733,7 @@
 
 "\n\
 @item -import\n\
-The @samp{-import} is accepted but ignored for backward compatiability.\n\
+The @samp{-import} is accepted but ignored for backward compatibility.\n\
 Octave can now support multi-dimensional HDF data and automatically\n\
 modifies variable names if they are invalid Octave identifiers.\n\
 \n\
@@ -810,25 +858,13 @@
   else
     {
       std::string fname = file_ops::tilde_expand (argv[i]);
-      bool use_zlib = false;
 
-      // Check if file exists, if it doesn't then also check with a 
-      // .mat extension
-      std::ifstream file_exist (fname.c_str ());
-      if (file_exist)
-       file_exist.close ();
-      else
-       {
-         fname.append (".mat");
-         std::ifstream file_mat_exist (fname.c_str ());
-         if (file_mat_exist)
-           file_mat_exist.close ();
-         else
-           {
-             gripe_file_open ("load", orig_fname);
-             return retval;
-           }
-       }
+      fname = find_file_to_load (fname, orig_fname);
+
+      if (error_state)
+       return retval;
+
+      bool use_zlib = false;
 
       if (format == LS_UNKNOWN)
        format = get_file_format (fname, orig_fname, use_zlib);
Index: src/octave.cc
===================================================================
RCS file: /cvs/octave/src/octave.cc,v
retrieving revision 1.226
diff -u -u -r1.226 octave.cc
--- src/octave.cc       15 Sep 2006 14:34:57 -0000      1.226
+++ src/octave.cc       14 Nov 2006 02:52:33 -0000
@@ -495,7 +495,9 @@
   bind_internal_variable ("page_screen_output", false);
   bind_internal_variable ("print_empty_dimensions", false);
 
+  disable_warning ("Octave:fopen-file-in-path");
   disable_warning ("Octave:function-name-clash");
+  disable_warning ("Octave:load-file-in-path");
 }
 
 // You guessed it.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]