forked from qt-creator/qt-creator
Utils: Centralize FilePath case sensitivity handling
This could or possibly should the target device's file name case sensitivity into account by diverting to IDevice. However, as this is expensive and we are in time-critical path here, we go with "good enough" for now. The first approximation is "Anything unusual is not case sensitive" which is better than "Any device equals the host". Change-Id: Ib3d4a627abebd96a7285a855af66e0c800767767 Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
@@ -210,6 +210,18 @@ bool FilePath::isNewerThan(const QDateTime &timeStamp) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Qt::CaseSensitivity FilePath::caseSensitivity() const
|
||||||
|
{
|
||||||
|
if (m_scheme.isEmpty())
|
||||||
|
return HostOsInfo::fileNameCaseSensitivity();
|
||||||
|
|
||||||
|
// FIXME: This could or possibly should the target device's file name case sensitivity
|
||||||
|
// into account by diverting to IDevice. However, as this is expensive and we are
|
||||||
|
// in time-critical path here, we go with "good enough" for now:
|
||||||
|
// The first approximation is "Anything unusual is not case sensitive"
|
||||||
|
return Qt::CaseSensitive;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Recursively resolves symlinks if \a filePath is a symlink.
|
Recursively resolves symlinks if \a filePath is a symlink.
|
||||||
To resolve symlinks anywhere in the path, see canonicalPath.
|
To resolve symlinks anywhere in the path, see canonicalPath.
|
||||||
@@ -994,12 +1006,9 @@ QDir FilePath::toDir() const
|
|||||||
|
|
||||||
bool FilePath::operator==(const FilePath &other) const
|
bool FilePath::operator==(const FilePath &other) const
|
||||||
{
|
{
|
||||||
if (m_scheme.isEmpty())
|
return QString::compare(m_data, other.m_data, caseSensitivity()) == 0
|
||||||
return QString::compare(m_data, other.m_data, HostOsInfo::fileNameCaseSensitivity()) == 0;
|
&& m_host == other.m_host
|
||||||
|
&& m_scheme == other.m_scheme;
|
||||||
// FIXME: This should take the host's file name case sensitivity into account.
|
|
||||||
// The first approximation here is "Anything unusual is not case sensitive"
|
|
||||||
return m_data == other.m_data && m_host == other.m_host && m_scheme == other.m_scheme;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FilePath::operator!=(const FilePath &other) const
|
bool FilePath::operator!=(const FilePath &other) const
|
||||||
@@ -1009,13 +1018,9 @@ bool FilePath::operator!=(const FilePath &other) const
|
|||||||
|
|
||||||
bool FilePath::operator<(const FilePath &other) const
|
bool FilePath::operator<(const FilePath &other) const
|
||||||
{
|
{
|
||||||
if (m_scheme.isEmpty())
|
const int cmp = QString::compare(m_data, other.m_data, caseSensitivity());
|
||||||
return QString::compare(m_data, other.m_data, HostOsInfo::fileNameCaseSensitivity()) < 0;
|
if (cmp != 0)
|
||||||
|
return cmp < 0;
|
||||||
// FIXME: This should take the host's file name case sensitivity into account.
|
|
||||||
// The first approximation here is "Anything unusual is not case sensitive"
|
|
||||||
if (m_data != other.m_data)
|
|
||||||
return m_data < other.m_data;
|
|
||||||
if (m_host != other.m_host)
|
if (m_host != other.m_host)
|
||||||
return m_host < other.m_host;
|
return m_host < other.m_host;
|
||||||
return m_scheme < other.m_scheme;
|
return m_scheme < other.m_scheme;
|
||||||
@@ -1046,7 +1051,7 @@ bool FilePath::isChildOf(const FilePath &s) const
|
|||||||
{
|
{
|
||||||
if (s.isEmpty())
|
if (s.isEmpty())
|
||||||
return false;
|
return false;
|
||||||
if (!m_data.startsWith(s.m_data, HostOsInfo::fileNameCaseSensitivity()))
|
if (!m_data.startsWith(s.m_data, caseSensitivity()))
|
||||||
return false;
|
return false;
|
||||||
if (m_data.size() <= s.m_data.size())
|
if (m_data.size() <= s.m_data.size())
|
||||||
return false;
|
return false;
|
||||||
@@ -1066,13 +1071,13 @@ bool FilePath::isChildOf(const QDir &dir) const
|
|||||||
/// \returns whether FilePath startsWith \a s
|
/// \returns whether FilePath startsWith \a s
|
||||||
bool FilePath::startsWith(const QString &s) const
|
bool FilePath::startsWith(const QString &s) const
|
||||||
{
|
{
|
||||||
return m_data.startsWith(s, HostOsInfo::fileNameCaseSensitivity());
|
return m_data.startsWith(s, caseSensitivity());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \returns whether FilePath endsWith \a s
|
/// \returns whether FilePath endsWith \a s
|
||||||
bool FilePath::endsWith(const QString &s) const
|
bool FilePath::endsWith(const QString &s) const
|
||||||
{
|
{
|
||||||
return m_data.endsWith(s, HostOsInfo::fileNameCaseSensitivity());
|
return m_data.endsWith(s, caseSensitivity());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FilePath::isDir() const
|
bool FilePath::isDir() const
|
||||||
@@ -1307,7 +1312,7 @@ void withNtfsPermissions(const std::function<void()> &task)
|
|||||||
std::hash<Utils::FilePath>::result_type
|
std::hash<Utils::FilePath>::result_type
|
||||||
std::hash<Utils::FilePath>::operator()(const std::hash<Utils::FilePath>::argument_type &fn) const
|
std::hash<Utils::FilePath>::operator()(const std::hash<Utils::FilePath>::argument_type &fn) const
|
||||||
{
|
{
|
||||||
if (Utils::HostOsInfo::fileNameCaseSensitivity() == Qt::CaseInsensitive)
|
if (fn.caseSensitivity() == Qt::CaseInsensitive)
|
||||||
return hash<string>()(fn.toString().toUpper().toStdString());
|
return hash<string>()(fn.toString().toUpper().toStdString());
|
||||||
return hash<string>()(fn.toString().toStdString());
|
return hash<string>()(fn.toString().toStdString());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,6 +146,8 @@ public:
|
|||||||
bool isDir() const;
|
bool isDir() const;
|
||||||
bool isNewerThan(const QDateTime &timeStamp) const;
|
bool isNewerThan(const QDateTime &timeStamp) const;
|
||||||
|
|
||||||
|
Qt::CaseSensitivity caseSensitivity() const;
|
||||||
|
|
||||||
FilePath relativeChildPath(const FilePath &parent) const;
|
FilePath relativeChildPath(const FilePath &parent) const;
|
||||||
FilePath relativePath(const FilePath &anchor) const;
|
FilePath relativePath(const FilePath &anchor) const;
|
||||||
FilePath pathAppended(const QString &str) const;
|
FilePath pathAppended(const QString &str) const;
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ private slots:
|
|||||||
void relativePath();
|
void relativePath();
|
||||||
void fromToString_data();
|
void fromToString_data();
|
||||||
void fromToString();
|
void fromToString();
|
||||||
|
void comparison_data();
|
||||||
|
void comparison();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QTemporaryDir tempDir;
|
QTemporaryDir tempDir;
|
||||||
@@ -329,5 +331,38 @@ void tst_fileutils::fromToString()
|
|||||||
QCOMPARE(copy.toString(), full);
|
QCOMPARE(copy.toString(), full);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_fileutils::comparison()
|
||||||
|
{
|
||||||
|
QFETCH(QString, left);
|
||||||
|
QFETCH(QString, right);
|
||||||
|
QFETCH(bool, hostSensitive);
|
||||||
|
QFETCH(bool, expected);
|
||||||
|
|
||||||
|
HostOsInfo::setOverrideFileNameCaseSensitivity(
|
||||||
|
hostSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive);
|
||||||
|
|
||||||
|
FilePath l = FilePath::fromString(left);
|
||||||
|
FilePath r = FilePath::fromString(right);
|
||||||
|
QCOMPARE(l == r, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_fileutils::comparison_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QString>("left");
|
||||||
|
QTest::addColumn<QString>("right");
|
||||||
|
QTest::addColumn<bool>("hostSensitive");
|
||||||
|
QTest::addColumn<bool>("expected");
|
||||||
|
|
||||||
|
QTest::newRow("r1") << "Abc" << "abc" << true << false;
|
||||||
|
QTest::newRow("r2") << "Abc" << "abc" << false << true;
|
||||||
|
QTest::newRow("r3") << "x://y/Abc" << "x://y/abc" << true << false;
|
||||||
|
QTest::newRow("r4") << "x://y/Abc" << "x://y/abc" << false << false;
|
||||||
|
|
||||||
|
QTest::newRow("s1") << "abc" << "abc" << true << true;
|
||||||
|
QTest::newRow("s2") << "abc" << "abc" << false << true;
|
||||||
|
QTest::newRow("s3") << "x://y/abc" << "x://y/abc" << true << true;
|
||||||
|
QTest::newRow("s4") << "x://y/abc" << "x://y/abc" << false << true;
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_APPLESS_MAIN(tst_fileutils)
|
QTEST_APPLESS_MAIN(tst_fileutils)
|
||||||
#include "tst_fileutils.moc"
|
#include "tst_fileutils.moc"
|
||||||
|
|||||||
Reference in New Issue
Block a user