diff options
author | Sebastian Holtermann <sebholt@xwmw.org> | 2019-03-13 17:50:06 (GMT) |
---|---|---|
committer | Sebastian Holtermann <sebholt@xwmw.org> | 2019-03-18 14:09:10 (GMT) |
commit | 103aa9e46a5a59dc2c41cc1fa1aa6dd406b2924b (patch) | |
tree | 3a6293db032850cbc5d17d20965d2e3b68c4d15f /Source | |
parent | 6f24c4e93f6ae897b793f894b67543d86c7de477 (diff) | |
download | CMake-103aa9e46a5a59dc2c41cc1fa1aa6dd406b2924b.zip CMake-103aa9e46a5a59dc2c41cc1fa1aa6dd406b2924b.tar.gz CMake-103aa9e46a5a59dc2c41cc1fa1aa6dd406b2924b.tar.bz2 |
cmFileTimeComparison: Use cmFileTime internally
This replaces OS dependent code in `cmFileTimeComparison` with `cmFileTime`
instances that provide the required file time load and comparison operations.
A new public `cmFileTimeComparison::Load` method is introduced that,
for a given file name, updates the `cmFileTimeComparison` cache on demand and
returns a `cmFileTime` instance on success.
Diffstat (limited to 'Source')
-rw-r--r-- | Source/CMakeLists.txt | 2 | ||||
-rw-r--r-- | Source/cmFileTimeComparison.cxx | 207 | ||||
-rw-r--r-- | Source/cmFileTimeComparison.h | 29 |
3 files changed, 54 insertions, 184 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 140754c..f615496 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -800,8 +800,6 @@ foreach(check endif() set_property(SOURCE cmFileTime.cxx APPEND PROPERTY COMPILE_DEFINITIONS CMake_${check}=${CMake_${check}}) - set_property(SOURCE cmFileTimeComparison.cxx APPEND PROPERTY - COMPILE_DEFINITIONS CMake_${check}=${CMake_${check}}) endforeach() # create a library used by the command line and the GUI diff --git a/Source/cmFileTimeComparison.cxx b/Source/cmFileTimeComparison.cxx index 8b3911e..5022cab 100644 --- a/Source/cmFileTimeComparison.cxx +++ b/Source/cmFileTimeComparison.cxx @@ -3,74 +3,40 @@ #include "cmFileTimeComparison.h" #include <string> -#include <time.h> #include <unordered_map> #include <utility> -// Use a platform-specific API to get file times efficiently. -#if !defined(_WIN32) || defined(__CYGWIN__) -# include "cm_sys_stat.h" -# define cmFileTimeComparison_Type struct stat -#else -# include "cmsys/Encoding.hxx" -# include <windows.h> -# define cmFileTimeComparison_Type FILETIME -#endif - class cmFileTimeComparisonInternal { public: - // Internal comparison method. - inline bool FileTimeCompare(const std::string& f1, const std::string& f2, + inline bool Load(std::string const& fname, cmFileTime& ftm); + inline bool FileTimeCompare(std::string const& f1, std::string const& f2, int* result); - bool FileTimesDiffer(const std::string& f1, const std::string& f2); + bool FileTimesDiffer(std::string const& f1, std::string const& f2); private: - typedef std::unordered_map<std::string, cmFileTimeComparison_Type> - FileStatsMap; + typedef std::unordered_map<std::string, cmFileTime> FileStatsMap; FileStatsMap Files; - - // Internal methods to lookup and compare modification times. - inline bool Stat(const std::string& fname, cmFileTimeComparison_Type* st); - inline int Compare(cmFileTimeComparison_Type* st1, - cmFileTimeComparison_Type* st2); - inline bool TimesDiffer(cmFileTimeComparison_Type* st1, - cmFileTimeComparison_Type* st2); }; -bool cmFileTimeComparisonInternal::Stat(const std::string& fname, - cmFileTimeComparison_Type* st) +bool cmFileTimeComparisonInternal::Load(std::string const& fname, + cmFileTime& ftm) { // Use the stored time if available. - cmFileTimeComparisonInternal::FileStatsMap::iterator fit = - this->Files.find(fname); - if (fit != this->Files.end()) { - *st = fit->second; - return true; - } - -#if !defined(_WIN32) || defined(__CYGWIN__) - // POSIX version. Use the stat function. - int res = ::stat(fname.c_str(), st); - if (res != 0) { + { + auto fit = this->Files.find(fname); + if (fit != this->Files.end()) { + ftm = fit->second; + return true; + } + } + // Read file time from OS + if (!ftm.Load(fname)) { return false; } -#else - // Windows version. Get the modification time from extended file - // attributes. - WIN32_FILE_ATTRIBUTE_DATA fdata; - if (!GetFileAttributesExW(cmsys::Encoding::ToWide(fname).c_str(), - GetFileExInfoStandard, &fdata)) { - return false; - } - - // Copy the file time to the output location. - *st = fdata.ftLastWriteTime; -#endif - - // Store the time for future use. - this->Files[fname] = *st; + // Store file time in cache + this->Files[fname] = ftm; return true; } @@ -84,133 +50,33 @@ cmFileTimeComparison::~cmFileTimeComparison() delete this->Internals; } -bool cmFileTimeComparison::FileTimeCompare(const std::string& f1, - const std::string& f2, int* result) +bool cmFileTimeComparison::Load(std::string const& fileName, + cmFileTime& fileTime) { - return this->Internals->FileTimeCompare(f1, f2, result); + return this->Internals->Load(fileName, fileTime); } -bool cmFileTimeComparison::FileTimesDiffer(const std::string& f1, - const std::string& f2) +bool cmFileTimeComparison::FileTimeCompare(std::string const& f1, + std::string const& f2, int* result) { - return this->Internals->FileTimesDiffer(f1, f2); -} - -int cmFileTimeComparisonInternal::Compare(cmFileTimeComparison_Type* s1, - cmFileTimeComparison_Type* s2) -{ -#if !defined(_WIN32) || defined(__CYGWIN__) -# if CMake_STAT_HAS_ST_MTIM - // Compare using nanosecond resolution. - if (s1->st_mtim.tv_sec < s2->st_mtim.tv_sec) { - return -1; - } - if (s1->st_mtim.tv_sec > s2->st_mtim.tv_sec) { - return 1; - } - if (s1->st_mtim.tv_nsec < s2->st_mtim.tv_nsec) { - return -1; - } - if (s1->st_mtim.tv_nsec > s2->st_mtim.tv_nsec) { - return 1; - } -# elif CMake_STAT_HAS_ST_MTIMESPEC - // Compare using nanosecond resolution. - if (s1->st_mtimespec.tv_sec < s2->st_mtimespec.tv_sec) { - return -1; - } - if (s1->st_mtimespec.tv_sec > s2->st_mtimespec.tv_sec) { - return 1; - } - if (s1->st_mtimespec.tv_nsec < s2->st_mtimespec.tv_nsec) { - return -1; - } - if (s1->st_mtimespec.tv_nsec > s2->st_mtimespec.tv_nsec) { - return 1; - } -# else - // Compare using 1 second resolution. - if (s1->st_mtime < s2->st_mtime) { - return -1; - } - if (s1->st_mtime > s2->st_mtime) { - return 1; - } -# endif - // Files have the same time. - return 0; -#else - // Compare using system-provided function. - return (int)CompareFileTime(s1, s2); -#endif + return this->Internals->FileTimeCompare(f1, f2, result); } -bool cmFileTimeComparisonInternal::TimesDiffer(cmFileTimeComparison_Type* s1, - cmFileTimeComparison_Type* s2) +bool cmFileTimeComparison::FileTimesDiffer(std::string const& f1, + std::string const& f2) { -#if !defined(_WIN32) || defined(__CYGWIN__) -# if CMake_STAT_HAS_ST_MTIM - // Times are integers in units of 1ns. - long long bil = 1000000000; - long long t1 = s1->st_mtim.tv_sec * bil + s1->st_mtim.tv_nsec; - long long t2 = s2->st_mtim.tv_sec * bil + s2->st_mtim.tv_nsec; - if (t1 < t2) { - return (t2 - t1) >= bil; - } - if (t2 < t1) { - return (t1 - t2) >= bil; - } - return false; -# elif CMake_STAT_HAS_ST_MTIMESPEC - // Times are integers in units of 1ns. - long long bil = 1000000000; - long long t1 = s1->st_mtimespec.tv_sec * bil + s1->st_mtimespec.tv_nsec; - long long t2 = s2->st_mtimespec.tv_sec * bil + s2->st_mtimespec.tv_nsec; - if (t1 < t2) { - return (t2 - t1) >= bil; - } - if (t2 < t1) { - return (t1 - t2) >= bil; - } - return false; -# else - // Times are integers in units of 1s. - if (s1->st_mtime < s2->st_mtime) { - return (s2->st_mtime - s1->st_mtime) >= 1; - } - if (s1->st_mtime > s2->st_mtime) { - return (s1->st_mtime - s2->st_mtime) >= 1; - } - return false; -# endif -#else - // Times are integers in units of 100ns. - LARGE_INTEGER t1; - LARGE_INTEGER t2; - t1.LowPart = s1->dwLowDateTime; - t1.HighPart = s1->dwHighDateTime; - t2.LowPart = s2->dwLowDateTime; - t2.HighPart = s2->dwHighDateTime; - if (t1.QuadPart < t2.QuadPart) { - return (t2.QuadPart - t1.QuadPart) >= static_cast<LONGLONG>(10000000); - } else if (t2.QuadPart < t1.QuadPart) { - return (t1.QuadPart - t2.QuadPart) >= static_cast<LONGLONG>(10000000); - } else { - return false; - } -#endif + return this->Internals->FileTimesDiffer(f1, f2); } -bool cmFileTimeComparisonInternal::FileTimeCompare(const std::string& f1, - const std::string& f2, +bool cmFileTimeComparisonInternal::FileTimeCompare(std::string const& f1, + std::string const& f2, int* result) { // Get the modification time for each file. - cmFileTimeComparison_Type s1; - cmFileTimeComparison_Type s2; - if (this->Stat(f1, &s1) && this->Stat(f2, &s2)) { + cmFileTime ft1, ft2; + if (this->Load(f1, ft1) && this->Load(f2, ft2)) { // Compare the two modification times. - *result = this->Compare(&s1, &s2); + *result = ft1.Compare(ft2); return true; } // No comparison available. Default to the same time. @@ -218,15 +84,14 @@ bool cmFileTimeComparisonInternal::FileTimeCompare(const std::string& f1, return false; } -bool cmFileTimeComparisonInternal::FileTimesDiffer(const std::string& f1, - const std::string& f2) +bool cmFileTimeComparisonInternal::FileTimesDiffer(std::string const& f1, + std::string const& f2) { // Get the modification time for each file. - cmFileTimeComparison_Type s1; - cmFileTimeComparison_Type s2; - if (this->Stat(f1, &s1) && this->Stat(f2, &s2)) { + cmFileTime ft1, ft2; + if (this->Load(f1, ft1) && this->Load(f2, ft2)) { // Compare the two modification times. - return this->TimesDiffer(&s1, &s2); + return ft1.DifferS(ft2); } // No comparison available. Default to different times. return true; diff --git a/Source/cmFileTimeComparison.h b/Source/cmFileTimeComparison.h index b4e4eb3..cc321f0 100644 --- a/Source/cmFileTimeComparison.h +++ b/Source/cmFileTimeComparison.h @@ -5,14 +5,13 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include "cmFileTime.h" #include <string> class cmFileTimeComparisonInternal; /** \class cmFileTimeComparison - * \brief Helper class for comparing file modification times. - * - * Compare file modification times or test if file modification times differ. + * \brief Caches file modification times in an internal map for fast lookups. */ class cmFileTimeComparison { @@ -24,19 +23,27 @@ public: cmFileTimeComparison& operator=(const cmFileTimeComparison&) = delete; /** - * Compare file modification times. - * Return 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. + * @brief Loads the file time from the cache or the file system. + * @return true on success */ - bool FileTimeCompare(const std::string& f1, const std::string& f2, + bool Load(std::string const& fileName, cmFileTime& fileTime); + + /** + * @brief Compare file modification times. + * @return 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. + */ + bool FileTimeCompare(std::string const& f1, std::string const& f2, int* result); /** - * Compare file modification times. Return true unless both files - * exist and have modification times less than 1 second apart. + * @brief Compare file modification times. + * @return true unless both files exist and have modification times less + * than 1 second apart. */ - bool FileTimesDiffer(const std::string& f1, const std::string& f2); + bool FileTimesDiffer(std::string const& f1, std::string const& f2); protected: cmFileTimeComparisonInternal* Internals; |