summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeLists.txt8
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CTest/cmCTestBuildHandler.cxx10
-rw-r--r--Source/cmDepends.cxx9
-rw-r--r--Source/cmDepends.h9
-rw-r--r--Source/cmDependsC.cxx12
-rw-r--r--Source/cmFileCopier.cxx2
-rw-r--r--Source/cmFileCopier.h4
-rw-r--r--Source/cmFileTime.cxx49
-rw-r--r--Source/cmFileTime.h130
-rw-r--r--Source/cmFileTimeCache.cxx57
-rw-r--r--Source/cmFileTimeCache.h51
-rw-r--r--Source/cmFileTimeComparison.cxx233
-rw-r--r--Source/cmFileTimeComparison.h45
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx17
-rw-r--r--Source/cm_utf8.c29
-rw-r--r--Source/cm_utf8.h4
-rw-r--r--Source/cmake.cxx43
-rw-r--r--Source/cmake.h6
19 files changed, 382 insertions, 338 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 696826f..596c7f5 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -236,8 +236,10 @@ set(SRCS
cmFileLockResult.h
cmFilePathChecksum.cxx
cmFilePathChecksum.h
- cmFileTimeComparison.cxx
- cmFileTimeComparison.h
+ cmFileTime.cxx
+ cmFileTime.h
+ cmFileTimeCache.cxx
+ cmFileTimeCache.h
cmFortranParserImpl.cxx
cmFSPermissions.cxx
cmFSPermissions.h
@@ -796,7 +798,7 @@ foreach(check
else()
set(CMake_${check} 0)
endif()
- set_property(SOURCE cmFileTimeComparison.cxx APPEND PROPERTY
+ set_property(SOURCE cmFileTime.cxx APPEND PROPERTY
COMPILE_DEFINITIONS CMake_${check}=${CMake_${check}})
endforeach()
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 4e637cc..5af288f 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,5 +1,5 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 14)
-set(CMake_VERSION_PATCH 20190317)
+set(CMake_VERSION_PATCH 20190319)
#set(CMake_VERSION_RC 1)
diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx
index 07bc7e7..8ea9a83 100644
--- a/Source/CTest/cmCTestBuildHandler.cxx
+++ b/Source/CTest/cmCTestBuildHandler.cxx
@@ -5,7 +5,7 @@
#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmDuration.h"
-#include "cmFileTimeComparison.h"
+#include "cmFileTimeCache.h"
#include "cmGeneratedFileStream.h"
#include "cmMakefile.h"
#include "cmProcessOutput.h"
@@ -503,7 +503,7 @@ void cmCTestBuildHandler::GenerateXMLHeader(cmXMLWriter& xml)
class cmCTestBuildHandler::FragmentCompare
{
public:
- FragmentCompare(cmFileTimeComparison* ftc)
+ FragmentCompare(cmFileTimeCache* ftc)
: FTC(ftc)
{
}
@@ -513,14 +513,14 @@ public:
// Order files by modification time. Use lexicographic order
// among files with the same time.
int result;
- if (this->FTC->FileTimeCompare(l, r, &result) && result != 0) {
+ if (this->FTC->Compare(l, r, &result) && result != 0) {
return result < 0;
}
return l < r;
}
private:
- cmFileTimeComparison* FTC = nullptr;
+ cmFileTimeCache* FTC = nullptr;
};
void cmCTestBuildHandler::GenerateXMLLaunched(cmXMLWriter& xml)
@@ -530,7 +530,7 @@ void cmCTestBuildHandler::GenerateXMLLaunched(cmXMLWriter& xml)
}
// Sort XML fragments in chronological order.
- cmFileTimeComparison ftc;
+ cmFileTimeCache ftc;
FragmentCompare fragmentCompare(&ftc);
typedef std::set<std::string, FragmentCompare> Fragments;
Fragments fragments(fragmentCompare);
diff --git a/Source/cmDepends.cxx b/Source/cmDepends.cxx
index c128b02..efadaf1 100644
--- a/Source/cmDepends.cxx
+++ b/Source/cmDepends.cxx
@@ -2,7 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmDepends.h"
-#include "cmFileTimeComparison.h"
+#include "cmFileTimeCache.h"
#include "cmGeneratedFileStream.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
@@ -177,8 +177,7 @@ bool cmDepends::CheckDependencies(
if (dependerExists) {
// The dependee and depender both exist. Compare file times.
int result = 0;
- if ((!this->FileComparison->FileTimeCompare(depender, dependee,
- &result) ||
+ if ((!this->FileTimeCache->Compare(depender, dependee, &result) ||
result < 0)) {
// The depender is older than the dependee.
regenerate = true;
@@ -195,8 +194,8 @@ bool cmDepends::CheckDependencies(
// The dependee exists, but the depender doesn't. Regenerate if the
// internalDepends file is older than the dependee.
int result = 0;
- if ((!this->FileComparison->FileTimeCompare(internalDependsFileName,
- dependee, &result) ||
+ if ((!this->FileTimeCache->Compare(internalDependsFileName, dependee,
+ &result) ||
result < 0)) {
// The depends-file is older than the dependee.
regenerate = true;
diff --git a/Source/cmDepends.h b/Source/cmDepends.h
index 20c91ca..fc6571d 100644
--- a/Source/cmDepends.h
+++ b/Source/cmDepends.h
@@ -12,7 +12,7 @@
#include <string>
#include <vector>
-class cmFileTimeComparison;
+class cmFileTimeCache;
class cmLocalGenerator;
/** \class cmDepends
@@ -72,10 +72,7 @@ public:
void Clear(const std::string& file);
/** Set the file comparison object */
- void SetFileComparison(cmFileTimeComparison* fc)
- {
- this->FileComparison = fc;
- }
+ void SetFileTimeCache(cmFileTimeCache* fc) { this->FileTimeCache = fc; }
protected:
// Write dependencies for the target file to the given stream.
@@ -101,7 +98,7 @@ protected:
// Flag for verbose output.
bool Verbose = false;
- cmFileTimeComparison* FileComparison = nullptr;
+ cmFileTimeCache* FileTimeCache = nullptr;
std::string Language;
diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx
index a85f5ee..58b4ebb 100644
--- a/Source/cmDependsC.cxx
+++ b/Source/cmDependsC.cxx
@@ -6,6 +6,7 @@
#include <utility>
#include "cmAlgorithms.h"
+#include "cmFileTime.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmSystemTools.h"
@@ -247,6 +248,8 @@ void cmDependsC::ReadCacheFile()
cmIncludeLines* cacheEntry = nullptr;
bool haveFileName = false;
+ cmFileTime cacheFileTime;
+ bool const cacheFileTimeGood = cacheFileTime.Load(this->CacheFileName);
while (cmSystemTools::GetLineFromStream(fin, line)) {
if (line.empty()) {
cacheEntry = nullptr;
@@ -256,11 +259,12 @@ void cmDependsC::ReadCacheFile()
// the first line after an empty line is the name of the parsed file
if (!haveFileName) {
haveFileName = true;
- int newer = 0;
- bool res =
- cmSystemTools::FileTimeCompare(this->CacheFileName, line, &newer);
- if (res && newer == 1) // cache is newer than the parsed file
+ cmFileTime fileTime;
+ bool const res = cacheFileTimeGood && fileTime.Load(line);
+ bool const newer = res && cacheFileTime.Newer(fileTime);
+
+ if (res && newer) // cache is newer than the parsed file
{
cacheEntry = new cmIncludeLines;
this->FileCache[line] = cacheEntry;
diff --git a/Source/cmFileCopier.cxx b/Source/cmFileCopier.cxx
index 560d893..8913e6d 100644
--- a/Source/cmFileCopier.cxx
+++ b/Source/cmFileCopier.cxx
@@ -532,7 +532,7 @@ bool cmFileCopier::InstallFile(const std::string& fromFile,
bool copy = true;
if (!this->Always) {
// If both files exist with the same time do not copy.
- if (!this->FileTimes.FileTimesDiffer(fromFile, toFile)) {
+ if (!this->FileTimes.DifferS(fromFile, toFile)) {
copy = false;
}
}
diff --git a/Source/cmFileCopier.h b/Source/cmFileCopier.h
index a11c371..003b8f6 100644
--- a/Source/cmFileCopier.h
+++ b/Source/cmFileCopier.h
@@ -5,7 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmFileTimeComparison.h"
+#include "cmFileTimeCache.h"
#include "cm_sys_stat.h"
#include "cmsys/RegularExpression.hxx"
@@ -28,7 +28,7 @@ protected:
cmMakefile* Makefile;
const char* Name;
bool Always;
- cmFileTimeComparison FileTimes;
+ cmFileTimeCache FileTimes;
// Whether to install a file not matching any expression.
bool MatchlessFiles;
diff --git a/Source/cmFileTime.cxx b/Source/cmFileTime.cxx
new file mode 100644
index 0000000..253457f
--- /dev/null
+++ b/Source/cmFileTime.cxx
@@ -0,0 +1,49 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmFileTime.h"
+
+#include <string>
+#include <time.h>
+
+// Use a platform-specific API to get file times efficiently.
+#if !defined(_WIN32) || defined(__CYGWIN__)
+# include "cm_sys_stat.h"
+#else
+# include "cmsys/Encoding.hxx"
+# include <windows.h>
+#endif
+
+bool cmFileTime::Load(std::string const& fileName)
+{
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ // POSIX version. Use the stat function.
+ struct stat fst;
+ if (::stat(fileName.c_str(), &fst) != 0) {
+ return false;
+ }
+# if CMake_STAT_HAS_ST_MTIM
+ // Nanosecond resolution
+ this->NS = fst.st_mtim.tv_sec * NsPerS + fst.st_mtim.tv_nsec;
+# elif CMake_STAT_HAS_ST_MTIMESPEC
+ // Nanosecond resolution
+ this->NS = fst.st_mtimespec.tv_sec * NsPerS + fst.st_mtimespec.tv_nsec;
+# else
+ // Second resolution
+ this->NS = fst.st_mtime * NsPerS;
+# endif
+#else
+ // Windows version. Get the modification time from extended file attributes.
+ WIN32_FILE_ATTRIBUTE_DATA fdata;
+ if (!GetFileAttributesExW(cmsys::Encoding::ToWide(fileName).c_str(),
+ GetFileExInfoStandard, &fdata)) {
+ return false;
+ }
+
+ // Copy the file time to the output location.
+ this->NS = (static_cast<NSC>(fdata.ftLastWriteTime.dwHighDateTime) << 32) |
+ static_cast<NSC>(fdata.ftLastWriteTime.dwLowDateTime);
+ // The file time resolution is 100 ns.
+ this->NS *= 100;
+#endif
+ return true;
+}
diff --git a/Source/cmFileTime.h b/Source/cmFileTime.h
new file mode 100644
index 0000000..4c8e556
--- /dev/null
+++ b/Source/cmFileTime.h
@@ -0,0 +1,130 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmFileTime_h
+#define cmFileTime_h
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <string>
+
+/** \class cmFileTime
+ * \brief Abstract file modification time with support for comparison with
+ * other file modification times.
+ */
+class cmFileTime
+{
+public:
+ typedef long long NSC;
+ static constexpr NSC NsPerS = 1000000000;
+
+ cmFileTime() = default;
+ ~cmFileTime() = default;
+
+ /**
+ * @brief Loads the file time of fileName from the file system
+ * @return true on success
+ */
+ bool Load(std::string const& fileName);
+
+ /**
+ * @brief Return true if this is older than ftm
+ */
+ bool Older(cmFileTime const& ftm) const { return (this->NS - ftm.NS) < 0; }
+
+ /**
+ * @brief Return true if this is newer than ftm
+ */
+ bool Newer(cmFileTime const& ftm) const { return (ftm.NS - this->NS) < 0; }
+
+ /**
+ * @brief Return true if this is the same as ftm
+ */
+ bool Equal(cmFileTime const& ftm) const { return this->NS == ftm.NS; }
+
+ /**
+ * @brief Return true if this is not the same as ftm
+ */
+ bool Differ(cmFileTime const& ftm) const { return this->NS != ftm.NS; }
+
+ /**
+ * @brief Compare file modification times.
+ * @return -1, 0, +1 for this older, same, or newer than ftm.
+ */
+ int Compare(cmFileTime const& ftm)
+ {
+ NSC const diff = this->NS - ftm.NS;
+ if (diff == 0) {
+ return 0;
+ }
+ return (diff < 0) ? -1 : 1;
+ }
+
+ // -- Comparison in second resolution
+
+ /**
+ * @brief Return true if this is at least a second older than ftm
+ */
+ bool OlderS(cmFileTime const& ftm) const
+ {
+ return (ftm.NS - this->NS) >= cmFileTime::NsPerS;
+ }
+
+ /**
+ * @brief Return true if this is at least a second newer than ftm
+ */
+ bool NewerS(cmFileTime const& ftm) const
+ {
+ return (this->NS - ftm.NS) >= cmFileTime::NsPerS;
+ }
+
+ /**
+ * @brief Return true if this is within the same second as ftm
+ */
+ bool EqualS(cmFileTime const& ftm) const
+ {
+ NSC diff = this->NS - ftm.NS;
+ if (diff < 0) {
+ diff = -diff;
+ }
+ return (diff < cmFileTime::NsPerS);
+ }
+
+ /**
+ * @brief Return true if this is older or newer than ftm by at least a second
+ */
+ bool DifferS(cmFileTime const& ftm) const
+ {
+ NSC diff = this->NS - ftm.NS;
+ if (diff < 0) {
+ diff = -diff;
+ }
+ return (diff >= cmFileTime::NsPerS);
+ }
+
+ /**
+ * @brief Compare file modification times.
+ * @return -1: this at least a second older, 0: this within the same second
+ * as ftm, +1: this at least a second newer than ftm.
+ */
+ int CompareS(cmFileTime const& ftm) const
+ {
+ NSC const diff = this->NS - ftm.NS;
+ if (diff <= -cmFileTime::NsPerS) {
+ return -1;
+ }
+ if (diff >= cmFileTime::NsPerS) {
+ return 1;
+ }
+ return 0;
+ }
+
+ /**
+ * @brief The file modification time in nanoseconds
+ */
+ NSC GetNS() const { return this->NS; }
+
+private:
+ NSC NS = 0;
+};
+
+#endif
diff --git a/Source/cmFileTimeCache.cxx b/Source/cmFileTimeCache.cxx
new file mode 100644
index 0000000..1fff6a9
--- /dev/null
+++ b/Source/cmFileTimeCache.cxx
@@ -0,0 +1,57 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmFileTimeCache.h"
+
+#include <string>
+#include <unordered_map>
+#include <utility>
+
+cmFileTimeCache::cmFileTimeCache() = default;
+
+cmFileTimeCache::~cmFileTimeCache() = default;
+
+bool cmFileTimeCache::Load(std::string const& fileName, cmFileTime& fileTime)
+{
+ // Use the stored time if available.
+ {
+ auto fit = this->FileTimes.find(fileName);
+ if (fit != this->FileTimes.end()) {
+ fileTime = fit->second;
+ return true;
+ }
+ }
+ // Read file time from OS
+ if (!fileTime.Load(fileName)) {
+ return false;
+ }
+ // Store file time in cache
+ this->FileTimes[fileName] = fileTime;
+ return true;
+}
+
+bool cmFileTimeCache::Compare(std::string const& f1, std::string const& f2,
+ int* result)
+{
+ // Get the modification time for each file.
+ cmFileTime ft1, ft2;
+ if (this->Load(f1, ft1) && this->Load(f2, ft2)) {
+ // Compare the two modification times.
+ *result = ft1.Compare(ft2);
+ return true;
+ }
+ // No comparison available. Default to the same time.
+ *result = 0;
+ return false;
+}
+
+bool cmFileTimeCache::DifferS(std::string const& f1, std::string const& f2)
+{
+ // Get the modification time for each file.
+ cmFileTime ft1, ft2;
+ if (this->Load(f1, ft1) && this->Load(f2, ft2)) {
+ // Compare the two modification times.
+ return ft1.DifferS(ft2);
+ }
+ // No comparison available. Default to different times.
+ return true;
+}
diff --git a/Source/cmFileTimeCache.h b/Source/cmFileTimeCache.h
new file mode 100644
index 0000000..a47904c
--- /dev/null
+++ b/Source/cmFileTimeCache.h
@@ -0,0 +1,51 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmFileTimeCache_h
+#define cmFileTimeCache_h
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include "cmFileTime.h"
+#include <string>
+#include <unordered_map>
+
+/** \class cmFileTimeCache
+ * \brief Caches file modification times in an internal map for fast lookups.
+ */
+class cmFileTimeCache
+{
+public:
+ cmFileTimeCache();
+ ~cmFileTimeCache();
+
+ cmFileTimeCache(const cmFileTimeCache&) = delete;
+ cmFileTimeCache& operator=(const cmFileTimeCache&) = delete;
+
+ /**
+ * @brief Loads the file time from the cache or the file system.
+ * @return true on success
+ */
+ 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 Compare(std::string const& f1, std::string const& f2, int* result);
+
+ /**
+ * @brief Compare file modification times.
+ * @return true unless both files exist and have modification times less
+ * than 1 second apart.
+ */
+ bool DifferS(std::string const& f1, std::string const& f2);
+
+private:
+ typedef std::unordered_map<std::string, cmFileTime> FileTimeMap;
+ FileTimeMap FileTimes;
+};
+
+#endif
diff --git a/Source/cmFileTimeComparison.cxx b/Source/cmFileTimeComparison.cxx
deleted file mode 100644
index 8b3911e..0000000
--- a/Source/cmFileTimeComparison.cxx
+++ /dev/null
@@ -1,233 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#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,
- int* result);
-
- bool FileTimesDiffer(const std::string& f1, const std::string& f2);
-
-private:
- typedef std::unordered_map<std::string, cmFileTimeComparison_Type>
- 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)
-{
- // 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) {
- 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;
- return true;
-}
-
-cmFileTimeComparison::cmFileTimeComparison()
-{
- this->Internals = new cmFileTimeComparisonInternal;
-}
-
-cmFileTimeComparison::~cmFileTimeComparison()
-{
- delete this->Internals;
-}
-
-bool cmFileTimeComparison::FileTimeCompare(const std::string& f1,
- const std::string& f2, int* result)
-{
- return this->Internals->FileTimeCompare(f1, f2, result);
-}
-
-bool cmFileTimeComparison::FileTimesDiffer(const std::string& f1,
- const std::string& f2)
-{
- 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
-}
-
-bool cmFileTimeComparisonInternal::TimesDiffer(cmFileTimeComparison_Type* s1,
- cmFileTimeComparison_Type* s2)
-{
-#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
-}
-
-bool cmFileTimeComparisonInternal::FileTimeCompare(const std::string& f1,
- const std::string& 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)) {
- // Compare the two modification times.
- *result = this->Compare(&s1, &s2);
- return true;
- }
- // No comparison available. Default to the same time.
- *result = 0;
- return false;
-}
-
-bool cmFileTimeComparisonInternal::FileTimesDiffer(const std::string& f1,
- const std::string& f2)
-{
- // Get the modification time for each file.
- cmFileTimeComparison_Type s1;
- cmFileTimeComparison_Type s2;
- if (this->Stat(f1, &s1) && this->Stat(f2, &s2)) {
- // Compare the two modification times.
- return this->TimesDiffer(&s1, &s2);
- }
- // No comparison available. Default to different times.
- return true;
-}
diff --git a/Source/cmFileTimeComparison.h b/Source/cmFileTimeComparison.h
deleted file mode 100644
index b4e4eb3..0000000
--- a/Source/cmFileTimeComparison.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#ifndef cmFileTimeComparison_h
-#define cmFileTimeComparison_h
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#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.
- */
-class cmFileTimeComparison
-{
-public:
- cmFileTimeComparison();
- ~cmFileTimeComparison();
-
- cmFileTimeComparison(const cmFileTimeComparison&) = delete;
- 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.
- */
- bool FileTimeCompare(const std::string& f1, const std::string& f2,
- int* result);
-
- /**
- * 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);
-
-protected:
- cmFileTimeComparisonInternal* Internals;
-};
-
-#endif
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index d1093be..f3d5a94 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -12,7 +12,7 @@
#include "cmAlgorithms.h"
#include "cmCustomCommandGenerator.h"
-#include "cmFileTimeComparison.h"
+#include "cmFileTimeCache.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
@@ -1273,12 +1273,11 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(
// happen when a new source file is added and CMake regenerates the
// project but no other sources were touched.
bool needRescanDependInfo = false;
- cmFileTimeComparison* ftc =
- this->GlobalGenerator->GetCMakeInstance()->GetFileComparison();
+ cmFileTimeCache* ftc =
+ this->GlobalGenerator->GetCMakeInstance()->GetFileTimeCache();
{
int result;
- if (!ftc->FileTimeCompare(internalDependFile, tgtInfo, &result) ||
- result < 0) {
+ if (!ftc->Compare(internalDependFile, tgtInfo, &result) || result < 0) {
if (verbose) {
std::ostringstream msg;
msg << "Dependee \"" << tgtInfo << "\" is newer than depender \""
@@ -1297,7 +1296,7 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(
dirInfoFile += "/CMakeFiles";
dirInfoFile += "/CMakeDirectoryInformation.cmake";
int result;
- if (!ftc->FileTimeCompare(internalDependFile, dirInfoFile, &result) ||
+ if (!ftc->Compare(internalDependFile, dirInfoFile, &result) ||
result < 0) {
if (verbose) {
std::ostringstream msg;
@@ -1318,7 +1317,7 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(
if (!needRescanDirInfo) {
cmDependsC checker;
checker.SetVerbose(verbose);
- checker.SetFileComparison(ftc);
+ checker.SetFileTimeCache(ftc);
// cmDependsC::Check() fills the vector validDependencies() with the
// dependencies for those files where they are still valid, i.e. neither
// the files themselves nor any files they depend on have changed.
@@ -1439,8 +1438,8 @@ bool cmLocalUnixMakefileGenerator3::ScanDependencies(
if (scanner) {
scanner->SetLocalGenerator(this);
- scanner->SetFileComparison(
- this->GlobalGenerator->GetCMakeInstance()->GetFileComparison());
+ scanner->SetFileTimeCache(
+ this->GlobalGenerator->GetCMakeInstance()->GetFileTimeCache());
scanner->SetLanguage(lang);
scanner->SetTargetDirectory(targetDir);
scanner->Write(ruleFileStream, internalRuleFileStream);
diff --git a/Source/cm_utf8.c b/Source/cm_utf8.c
index 52af4a6..62e7e8c 100644
--- a/Source/cm_utf8.c
+++ b/Source/cm_utf8.c
@@ -2,6 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cm_utf8.h"
+#include <string.h>
+
/*
RFC 3629
07-bit: 0xxxxxxx
@@ -71,7 +73,34 @@ const char* cm_utf8_decode_character(const char* first, const char* last,
return 0;
}
+ /* UTF-16 surrogate halves. */
+ if (0xD800 <= uc && uc <= 0xDFFF) {
+ return 0;
+ }
+
+ /* Invalid codepoints. */
+ if (0x10FFFF < uc) {
+ return 0;
+ }
+
*pc = uc;
return first;
}
}
+
+int cm_utf8_is_valid(const char* s)
+{
+ if (!s) {
+ return 0;
+ }
+
+ const char* last = s + strlen(s);
+ const char* pos = s;
+ unsigned int pc;
+
+ while (pos != last && (pos = cm_utf8_decode_character(pos, last, &pc))) {
+ /* Nothing to do. */
+ }
+
+ return pos == last;
+}
diff --git a/Source/cm_utf8.h b/Source/cm_utf8.h
index fcb43e0..27dc559 100644
--- a/Source/cm_utf8.h
+++ b/Source/cm_utf8.h
@@ -13,6 +13,10 @@ extern "C" {
const char* cm_utf8_decode_character(const char* first, const char* last,
unsigned int* pc);
+/** Returns whether a C string is a sequence of valid UTF-8 encoded Unicode
+ codepoints. Returns non-zero on success. */
+int cm_utf8_is_valid(const char* s);
+
#ifdef __cplusplus
} /* extern "C" */
#endif
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 08e284e..e1b775e 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -9,7 +9,7 @@
#include "cmDocumentationFormatter.h"
#include "cmDuration.h"
#include "cmExternalMakefileProjectGenerator.h"
-#include "cmFileTimeComparison.h"
+#include "cmFileTimeCache.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmGlobalGeneratorFactory.h"
@@ -138,7 +138,7 @@ cmake::cmake(Role role, cmState::Mode mode)
this->DebugOutput = false;
this->DebugTryCompile = false;
this->ClearBuildSystem = false;
- this->FileComparison = new cmFileTimeComparison;
+ this->FileTimeCache = new cmFileTimeCache;
this->State = new cmState;
this->State->SetMode(mode);
@@ -222,7 +222,7 @@ cmake::~cmake()
#ifdef CMAKE_BUILD_WITH_CMAKE
delete this->VariableWatch;
#endif
- delete this->FileComparison;
+ delete this->FileTimeCache;
}
#if defined(CMAKE_BUILD_WITH_CMAKE)
@@ -2139,7 +2139,7 @@ int cmake::CheckBuildSystem()
std::string dep_newest = *dep++;
for (; dep != depends.end(); ++dep) {
int result = 0;
- if (this->FileComparison->FileTimeCompare(dep_newest, *dep, &result)) {
+ if (this->FileTimeCache->Compare(dep_newest, *dep, &result)) {
if (result < 0) {
dep_newest = *dep;
}
@@ -2158,7 +2158,7 @@ int cmake::CheckBuildSystem()
std::string out_oldest = *out++;
for (; out != outputs.end(); ++out) {
int result = 0;
- if (this->FileComparison->FileTimeCompare(out_oldest, *out, &result)) {
+ if (this->FileTimeCache->Compare(out_oldest, *out, &result)) {
if (result > 0) {
out_oldest = *out;
}
@@ -2175,8 +2175,7 @@ int cmake::CheckBuildSystem()
// If any output is older than any dependency then rerun.
{
int result = 0;
- if (!this->FileComparison->FileTimeCompare(out_oldest, dep_newest,
- &result) ||
+ if (!this->FileTimeCache->Compare(out_oldest, dep_newest, &result) ||
result < 0) {
if (verbose) {
std::ostringstream msg;
@@ -2431,20 +2430,22 @@ static bool cmakeCheckStampFile(const std::string& stampName)
}
// Compare the stamp dependencies against the dependency file itself.
- cmFileTimeComparison ftc;
- std::string dep;
- while (cmSystemTools::GetLineFromStream(fin, dep)) {
- int result;
- if (!dep.empty() && dep[0] != '#' &&
- (!ftc.FileTimeCompare(stampDepends, dep, &result) || result < 0)) {
- // The stamp depends file is older than this dependency. The
- // build system is really out of date.
- std::cout << "CMake is re-running because " << stampName
- << " is out-of-date.\n";
- std::cout << " the file '" << dep << "'\n";
- std::cout << " is newer than '" << stampDepends << "'\n";
- std::cout << " result='" << result << "'\n";
- return false;
+ {
+ cmFileTimeCache ftc;
+ std::string dep;
+ while (cmSystemTools::GetLineFromStream(fin, dep)) {
+ int result;
+ if (!dep.empty() && dep[0] != '#' &&
+ (!ftc.Compare(stampDepends, dep, &result) || result < 0)) {
+ // The stamp depends file is older than this dependency. The
+ // build system is really out of date.
+ std::cout << "CMake is re-running because " << stampName
+ << " is out-of-date.\n";
+ std::cout << " the file '" << dep << "'\n";
+ std::cout << " is newer than '" << stampDepends << "'\n";
+ std::cout << " result='" << result << "'\n";
+ return false;
+ }
}
}
diff --git a/Source/cmake.h b/Source/cmake.h
index 1ffeabc..f8a2319 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -26,7 +26,7 @@
class cmExternalMakefileProjectGeneratorFactory;
class cmFileAPI;
-class cmFileTimeComparison;
+class cmFileTimeCache;
class cmGlobalGenerator;
class cmGlobalGeneratorFactory;
class cmMakefile;
@@ -329,7 +329,7 @@ public:
/**
* Get the file comparison class
*/
- cmFileTimeComparison* GetFileComparison() { return this->FileComparison; }
+ cmFileTimeCache* GetFileTimeCache() { return this->FileTimeCache; }
// Do we want debug output during the cmake run.
bool GetDebugOutput() { return this->DebugOutput; }
@@ -509,7 +509,7 @@ private:
std::unordered_set<std::string> HeaderFileExtensionsSet;
bool ClearBuildSystem;
bool DebugTryCompile;
- cmFileTimeComparison* FileComparison;
+ cmFileTimeCache* FileTimeCache;
std::string GraphVizFile;
InstalledFilesMap InstalledFiles;