ソースを参照

ENH: Adding kwsys::SystemTools::FileTimeCompare method to compare file modification times with the highest resolution possible on the file system.

Brad King 21 年 前
コミット
e2ec4a1845

+ 0 - 31
Source/cmSystemTools.cxx

@@ -1327,34 +1327,3 @@ bool cmSystemTools::PutEnv(const char* value)
   localEnvironment.push_back(envVar);
   return ret == 0;
 }
-
-bool cmSystemTools::FileTimeCompare(const char* f1, const char* f2,
-                                    int* result)
-{
-  struct stat stat1, stat2;
-  if(stat(f1, &stat1) == 0 && stat(f2, &stat2) == 0)
-    {
-    *result = 0;
-    if(stat1.st_mtime < stat2.st_mtime)
-      {
-      *result = -1;
-      }
-    else if(stat1.st_mtime > stat2.st_mtime)
-      {
-      *result = 1;
-      }
-#if 0
-    // TODO: Support resolution higher than one second.
-    // Use st_mtim.tv_nsec if available and GetFileTime on Windows.
-    else if(stat1.st_mtim.tv_nsec < stat2.st_mtim.tv_nsec)
-      {
-      *result = 1;
-      }
-#endif
-    return true;
-    }
-  else
-    {
-    return false;
-    }
-}

+ 0 - 6
Source/cmSystemTools.h

@@ -295,12 +295,6 @@ public:
       of the form var=value */
   static bool PutEnv(const char* value);
 
-  /** Compare file modification times.
-      Returns true for successful comparison and false for error.
-      When true is returned, result has -1, 0, +1 for
-      f1 older, same, or newer than f2.  */
-  static bool FileTimeCompare(const char* f1, const char* f2,
-                              int* result);
 private:
   static bool s_ForceUnixPaths;
   static bool s_RunCommandHideConsole;

+ 84 - 0
Source/kwsys/SystemTools.cxx

@@ -693,6 +693,90 @@ bool SystemTools::FileExists(const char* filename)
 }
 
 
+bool SystemTools::FileTimeCompare(const char* f1, const char* f2,
+                                  int* result)
+{
+  // Default to same time.
+  *result = 0;
+#if !defined(_WIN32) || defined(__CYGWIN__)
+  // POSIX version.  Use stat function to get file modification time.
+  struct stat s1;
+  if(stat(f1, &s1) != 0)
+    {
+    return false;
+    }
+  struct stat s2;
+  if(stat(f2, &s2) != 0)
+    {
+    return false;
+    }
+# if KWSYS_STAT_HAS_ST_MTIM
+  // Compare using nanosecond resolution.
+  if(s1.st_mtim.tv_sec < s2.st_mtim.tv_sec)
+    {
+    *result = -1;
+    }
+  else if(s1.st_mtim.tv_sec > s2.st_mtim.tv_sec)
+    {
+    *result = 1;
+    }
+  else if(s1.st_mtim.tv_nsec < s2.st_mtim.tv_nsec)
+    {
+    *result = -1;
+    }
+  else if(s1.st_mtim.tv_nsec > s2.st_mtim.tv_nsec)
+    {
+    *result = 1;
+    }
+# else
+  // Compare using 1 second resolution.
+  if(s1.st_mtime < s2.st_mtime)
+    {
+    *result = -1;
+    }
+  else if(s1.st_mtime > s2.st_mtime)
+    {
+    *result = 1;
+    }
+# endif
+#else
+  // Windows version.  Create file handles and get the modification times.
+  HANDLE hf1 = CreateFile(f1, GENERIC_READ, FILE_SHARE_READ,
+                          NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS,
+                          NULL);
+  if(hf1 == INVALID_HANDLE_VALUE)
+    {
+    return false;
+    }
+  FILETIME tf1;
+  if(!GetFileTime(hf1, 0, 0, &tf1))
+    {
+    CloseHandle(hf1);
+    return false;
+    }
+  CloseHandle(hf1);
+  HANDLE hf2 = CreateFile(f2, GENERIC_READ, FILE_SHARE_READ,
+                          NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS,
+                          NULL);
+  if(hf2 == INVALID_HANDLE_VALUE)
+    {
+    return false;
+    }
+  FILETIME tf2;
+  if(!GetFileTime(hf2, 0, 0, &tf2))
+    {
+    CloseHandle(hf2);
+    return false;
+    }
+  CloseHandle(hf2);
+
+  // Compare the file times using resolution provided by system call.
+  *result = (int)CompareFileTime(&tf1, &tf2);
+#endif
+  return true;
+}
+
+
 // Return a capitalized string (i.e the first letter is uppercased, all other
 // are lowercased)
 kwsys_stl::string SystemTools::Capitalized(const kwsys_stl::string& s)

+ 8 - 0
Source/kwsys/SystemTools.hxx.in

@@ -139,6 +139,14 @@ public:
   static bool FileExists(const char* filename);
   
   static unsigned long FileLength(const char *filename);
+
+  /** Compare file modification times.
+      Returns true for successful comparison and false for error.
+      When true is returned, result has -1, 0, +1 for
+      f1 older, same, or newer than f2.  */
+  static bool FileTimeCompare(const char* f1, const char* f2,
+                              int* result);
+
   /**
    *  Add the paths from the environment variable PATH to the 
    *  string vector passed in.  If env is set then the value