For PR789:
authorReid Spencer <rspencer@reidspencer.com>
Thu, 29 Mar 2007 16:43:20 +0000 (16:43 +0000)
committerReid Spencer <rspencer@reidspencer.com>
Thu, 29 Mar 2007 16:43:20 +0000 (16:43 +0000)
* Add a method: bool isAbsolute() const, which determines if the path name
  is absolute or not.
* Implement caching of file status information in the Path object. Allow it
  to be updated forcefully or lazily re-fetched from the cached value.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35456 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/System/Path.h
lib/System/Unix/Path.inc
lib/System/Win32/Path.inc

index f6b2be0fdf9081e7664287cda526c8f1387d28f6..8192dc42929ac61cc0034b7eab200ecf7171e9ed 100644 (file)
@@ -123,7 +123,7 @@ namespace sys {
       /// Find the path to a library using its short name. Use the system
       /// dependent library paths to locate the library.
       /// @brief Find a library.
-      static Path  FindLibrary(std::string& short_name);
+      static Path FindLibrary(std::string& short_name);
 
       /// Construct a path to the default LLVM configuration directory. The
       /// implementation must ensure that this is a well-known (same on many
@@ -162,14 +162,14 @@ namespace sys {
       /// provided so that they can be used to indicate null or error results in
       /// other lib/System functionality.
       /// @brief Construct an empty (and invalid) path.
-      Path() : path() {}
+      Path() : path(), status(0) {}
 
       /// This constructor will accept a std::string as a path. No checking is
       /// done on this path to determine if it is valid. To determine validity
       /// of the path, use the isValid method. 
       /// @param p The path to assign.
       /// @brief Construct a Path from a string.
-      explicit Path(const std::string& p) : path(p) {}
+      explicit Path(const std::string& p) : path(p), status(0) {}
 
     /// @}
     /// @name Operators
@@ -265,6 +265,11 @@ namespace sys {
       /// @brief Determines if the path references the root directory.
       bool isRootDirectory() const;
 
+      /// This function determines if the path name is absolute, as opposed to
+      /// relative. 
+      /// @breif Determine if the path is absolute.
+      bool isAbsolute() const;
+
       /// This function opens the file associated with the path name provided by
       /// the Path object and reads its magic number. If the magic number at the
       /// start of the file matches \p magic, true is returned. In all other
@@ -352,7 +357,11 @@ namespace sys {
       /// of the file system.  This returns false on success, or true on error
       /// and fills in the specified error string if specified.
       /// @brief Get file status.
-      bool getFileStatus(FileStatus &Status, std::string *Error = 0) const;
+      bool getFileStatus(
+          FileStatus &Status,       ///< The resulting file status
+          bool forceUpdate = false, ///< Force an update from the file system
+          std::string *Error = 0    ///< Optional place to return an error msg.
+      ) const;
 
     /// @}
     /// @name Path Mutators
@@ -511,6 +520,7 @@ namespace sys {
     /// @{
     private:
       mutable std::string path;   ///< Storage for the path name.
+      mutable FileStatus *status; ///< Status information.
 
     /// @}
   };
index 9802b7e00da753cb9e01d4b9b0461412f26a3640..b155213ec627edbeca10fb11f6c2c0b161009544 100644 (file)
@@ -79,6 +79,12 @@ Path::isValid() const {
   return i >= len; 
 }
 
+bool 
+Path::isAbsolute() const {
+  if (path.empty())
+    return false;
+  return path[0] == '/';
+} 
 Path
 Path::GetRootDirectory() {
   Path result;
@@ -357,18 +363,22 @@ Path::getLast() const {
 }
 
 bool
-Path::getFileStatus(FileStatus &info, std::string *ErrStr) const {
-  struct stat buf;
-  if (0 != stat(path.c_str(), &buf))
-    return MakeErrMsg(ErrStr, 
-      path + ": can't get status of file '" + path + "'");
-  info.fileSize = buf.st_size;
-  info.modTime.fromEpochTime(buf.st_mtime);
-  info.mode = buf.st_mode;
-  info.user = buf.st_uid;
-  info.group = buf.st_gid;
-  info.isDir  = S_ISDIR(buf.st_mode);
-  info.isFile = S_ISREG(buf.st_mode);
+Path::getFileStatus(FileStatus &info, bool update, std::string *ErrStr) const {
+  if (status == 0 || update) {
+    struct stat buf;
+    if (0 != stat(path.c_str(), &buf))
+      return MakeErrMsg(ErrStr, path + ": can't get status of file");
+    if (status == 0)
+      status = new FileStatus;
+    status->fileSize = buf.st_size;
+    status->modTime.fromEpochTime(buf.st_mtime);
+    status->mode = buf.st_mode;
+    status->user = buf.st_uid;
+    status->group = buf.st_gid;
+    status->isDir  = S_ISDIR(buf.st_mode);
+    status->isFile = S_ISREG(buf.st_mode);
+  }
+  info = *status;
   return false;
 }
 
index 1eee2bb3c1f795390dca1acc518e39267a531a9e..1f809ecfa56d8b7a2207ddf8af9e7bfe1fa3751f 100644 (file)
@@ -105,6 +105,13 @@ Path::isValid() const {
   return true;
 }
 
+bool 
+Path::isAbsolute() const {
+  if (path.length() < 3)
+    return false;
+  return path[0] == 'C' && path[1] == ':' && path[2] == '\\';
+} 
+
 static Path *TempDirectory = NULL;
 
 Path
@@ -294,24 +301,30 @@ Path::getLast() const {
 }
 
 bool
-Path::getFileStatus(FileStatus &info, std::string *ErrStr) const {
-  WIN32_FILE_ATTRIBUTE_DATA fi;
-  if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi))
-    return MakeErrMsg(ErrStr, "getStatusInfo():" + std::string(path) +
-                    ": Can't get status: ");
+Path::getFileStatus(FileStatus &info, bool update, std::string *ErrStr) const {
+  if (status == 0 || update) {
+    WIN32_FILE_ATTRIBUTE_DATA fi;
+    if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi))
+      return MakeErrMsg(ErrStr, "getStatusInfo():" + std::string(path) +
+                      ": Can't get status: ");
 
-  info.fileSize = fi.nFileSizeHigh;
-  info.fileSize <<= sizeof(fi.nFileSizeHigh)*8;
-  info.fileSize += fi.nFileSizeLow;
+    if (status == 0)
+      status = new FileStatus;
 
-  info.mode = fi.dwFileAttributes & FILE_ATTRIBUTE_READONLY ? 0555 : 0777;
-  info.user = 9999;    // Not applicable to Windows, so...
-  info.group = 9999;   // Not applicable to Windows, so...
+    status->fileSize = fi.nFileSizeHigh;
+    status->fileSize <<= sizeof(fi.nFileSizeHigh)*8;
+    status->fileSize += fi.nFileSizeLow;
 
-  __int64 ft = *reinterpret_cast<__int64*>(&fi.ftLastWriteTime);
-  info.modTime.fromWin32Time(ft);
+    status->mode = fi.dwFileAttributes & FILE_ATTRIBUTE_READONLY ? 0555 : 0777;
+    status->user = 9999;    // Not applicable to Windows, so...
+    status->group = 9999;   // Not applicable to Windows, so...
 
-  info.isDir = fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
+    __int64 ft = *reinterpret_cast<__int64*>(&fi.ftLastWriteTime);
+    status->modTime.fromWin32Time(ft);
+
+    status->isDir = fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
+  }
+  info = *status;
   return false;
 }