changeset 5138:5fa9670b5956

[project @ 2005-02-09 23:13:03 by jwe]
author jwe
date Wed, 09 Feb 2005 23:13:03 +0000
parents 5ee7da8b8a4b
children f2858bbf0277
files ChangeLog configure.in liboctave/ChangeLog liboctave/file-ops.cc liboctave/file-ops.h src/ChangeLog src/syscalls.cc src/variables.cc
diffstat 8 files changed, 159 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2005-02-09  John W. Eaton  <jwe@octave.org>
+
+	* configure.in: Check for canonicalize_file_name and resolvepath.
+
 2005-02-02  John W. Eaton  <jwe@octave.org>
 
 	* config.guess, config.sub: Update from FSF sources.
--- a/configure.in
+++ b/configure.in
@@ -29,7 +29,7 @@
 EXTERN_CXXFLAGS="$CXXFLAGS"
 
 AC_INIT
-AC_REVISION($Revision: 1.459 $)
+AC_REVISION($Revision: 1.460 $)
 AC_PREREQ(2.57)
 AC_CONFIG_SRCDIR([src/octave.cc])
 AC_CONFIG_HEADER(config.h)
@@ -981,15 +981,16 @@
 
 ### Checks for functions and variables.
 
-AC_CHECK_FUNCS(atexit basename bcopy bzero dup2 endgrent endpwent execvp \
-  fcntl fork getcwd getegid geteuid getgid getgrent getgrgid \
-  getgrnam getpgrp getpid getppid getpwent getpwuid gettimeofday \
-  getuid getwd _kbhit kill link localtime_r lstat memmove mkdir \
-  mkfifo mkstemp on_exit pipe poll putenv raise readlink rename \
-  rindex rmdir round select setgrent setpwent setvbuf sigaction \
-  siglongjmp sigpending sigprocmask sigsuspend stat strcasecmp strdup \
-  strerror strftime stricmp strncasecmp strnicmp strptime symlink \
-  tempnam umask unlink usleep vfprintf vsprintf vsnprintf waitpid)
+AC_CHECK_FUNCS(atexit basename bcopy bzero canonicalize_file_name \
+  dup2 endgrent endpwent execvp fcntl fork getcwd getegid geteuid \
+  getgid getgrent getgrgid getgrnam getpgrp getpid getppid getpwent \
+  getpwuid gettimeofday getuid getwd _kbhit kill link localtime_r \
+  lstat memmove mkdir mkfifo mkstemp on_exit pipe poll putenv raise \
+  readlink rename resolvepath rindex rmdir round select setgrent \
+  setpwent setvbuf sigaction siglongjmp sigpending sigprocmask \
+  sigsuspend stat strcasecmp strdup strerror strftime stricmp \
+  strncasecmp strnicmp strptime symlink tempnam umask unlink usleep \
+  vfprintf vsprintf vsnprintf waitpid)
 
 OCTAVE_SMART_PUTENV
 
--- a/liboctave/ChangeLog
+++ b/liboctave/ChangeLog
@@ -1,5 +1,8 @@
 2005-02-09  John W. Eaton  <jwe@octave.org>
 
+	* file-ops.cc (file_ops::canonicalize_file_name): New functions.
+	* file-ops.h: Provide decls.
+
 	* kpse.cc (kpse_tilde_expand): Simply return NAME if it is empty.
 
 2005-02-08  John W. Eaton  <jwe@octave.org>
--- a/liboctave/file-ops.cc
+++ b/liboctave/file-ops.cc
@@ -311,6 +311,88 @@
   return status;
 }
 
+std::string
+file_ops::canonicalize_file_name (const std::string& name)
+{
+  std::string msg;
+  return canonicalize_file_name (name, msg);
+}
+
+std::string
+file_ops::canonicalize_file_name (const std::string& name, std::string& msg)
+{
+  msg = std::string ();
+
+  std::string retval;
+
+#if defined (HAVE_CANONICALIZE_FILE_NAME)
+
+  char *tmp = ::canonicalize_file_name (name.c_str ());
+
+  if (tmp)
+    {
+      retval = tmp;
+      ::free (tmp);
+    }
+
+#elif defined (HAVE_RESOLVEPATH)
+
+#if !defined (errno)
+extern int errno;
+#endif
+
+#if !defined (__set_errno)
+# define __set_errno(Val) errno = (Val)
+#endif
+
+  if (name.empty ())
+    {
+      __set_errno (ENOENT);
+      return retval;
+    }
+
+  // All known hosts with resolvepath (e.g. Solaris 7) don't turn
+  // relative names into absolute ones, so prepend the working
+  // directory if the path is not absolute.
+
+  name = octave_env::make_absolute (name);
+
+  size_t resolved_size = name.length ();
+
+  while (1)
+    {
+      resolved_size = 2 * resolved_size + 1;
+
+      OCTAVE_LOCAL_BUFFER (char, resolved, resolved_size);
+
+      resolved_len = ::resolvepath (name, resolved, resolved_size);
+
+      if (resolved_len < 0)
+	break;
+
+      if (resolved_len < resolved_size)
+	{
+	  retval = resolved;
+	  break;
+	}
+    }
+
+#else
+
+  // XXX FIXME XXX -- provide replacement here...
+  retval = name;
+
+#endif
+
+  if (retval.empty ())
+    {
+      using namespace std;
+      msg = ::strerror (errno);
+    }
+
+  return retval;
+}
+
 // We provide a replacement for tempnam().
 
 std::string
--- a/liboctave/file-ops.h
+++ b/liboctave/file-ops.h
@@ -55,6 +55,9 @@
   static int rmdir (const std::string&);
   static int rmdir (const std::string&, std::string&);
 
+  static std::string canonicalize_file_name (const std::string&);
+  static std::string canonicalize_file_name (const std::string&, std::string&);
+
   static std::string tempnam (const std::string&, const std::string&);
   static std::string tempnam (const std::string&, const std::string&,
 			      std::string&);
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,10 @@
+2005-02-09  John W. Eaton  <jwe@octave.org>
+
+	* variables.cc (same_file): New static function.
+	(symbol_out_of_date): Use it.
+
+	* syscalls.cc (Fcanonicalize_file_name): New function.
+
 2005-02-08  Walter Landry  <landry@osc.edu>
 
 	* symtab.h (symbol_record::mark_as_command): Avoid AIX compiler error.
--- a/src/syscalls.cc
+++ b/src/syscalls.cc
@@ -190,7 +190,7 @@
 		    exec_args[i+1] = tmp[i];
 		}
 	      else
-		error ("exec: arguments must be strings");
+		error ("exec: arguments must be character strings");
 	    }
 	  else
 	    {
@@ -942,6 +942,37 @@
   return retval;
 }
 
+DEFUN (canonicalize_file_name, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {[@var{cname}, @var{status}, @var{msg}]} canonicalize_file_name (@var{name})\n\
+Return the canonical name of file @var{name}.\n\
+@end deftypefn")
+{
+  octave_value_list retval;
+
+  if (args.length () == 1)
+    {
+      std::string name = args(0).string_value ();
+
+      if (! error_state)
+	{
+	  std::string msg;
+
+	  std::string result = file_ops::canonicalize_file_name (name, msg);
+
+	  retval(2) = msg;
+	  retval(1) = msg.empty () ? 0 : -1;
+	  retval(0) = result;
+	}
+      else
+	error ("canonicalize_file_name: argument must be a character string");
+    }
+  else
+    print_usage ("canonicalize_file_name");
+
+  return retval;
+}
+
 #if !defined (O_NONBLOCK) && defined (O_NDELAY)
 #define O_NONBLOCK O_NDELAY
 #endif
--- a/src/variables.cc
+++ b/src/variables.cc
@@ -957,6 +957,20 @@
   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 ());
+}
+
 // Is there a corresponding function file that is newer than the
 // symbol definition?
 
@@ -994,9 +1008,7 @@
 		    (Vload_path_dir_path.find_first_of (names),
 		     octave_env::getcwd ());
 
-		  if (file != ff)
-		    retval = true;
-		  else
+		  if (same_file (file, ff))
 		    {
 		      tmp->mark_fcn_file_up_to_date (octave_time ());
 
@@ -1005,6 +1017,8 @@
 		      if (fs && fs.is_newer (tp))
 			retval = true;
 		    }
+		  else
+		    retval = true;
 		}
 	    }
 	}