summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qdir.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/io/qdir.cpp')
-rw-r--r--src/corelib/io/qdir.cpp110
1 files changed, 58 insertions, 52 deletions
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index 92e69baee9..a038f125cb 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -57,9 +57,8 @@
#include "qfilesystemengine_p.h"
#include <qstringbuilder.h>
-#ifdef QT_BUILD_CORE_LIB
-# include "qresource.h"
-# include "private/qcoreglobaldata_p.h"
+#ifndef QT_BOOTSTRAPPED
+# include "qreadwritelock.h"
#endif
#include <algorithm>
@@ -91,13 +90,13 @@ enum {
};
// Return the length of the root part of an absolute path, for use by cleanPath(), cd().
-static int rootLength(const QString &name, bool allowUncPaths)
+static qsizetype rootLength(QStringView name, bool allowUncPaths)
{
- const int len = name.length();
+ const qsizetype len = name.size();
// starts with double slash
if (allowUncPaths && name.startsWith(QLatin1String("//"))) {
// Server name '//server/path' is part of the prefix.
- const int nextSlash = name.indexOf(QLatin1Char('/'), 2);
+ const qsizetype nextSlash = name.indexOf(u'/', 2);
return nextSlash >= 0 ? nextSlash + 1 : len;
}
#if defined(Q_OS_WIN)
@@ -121,16 +120,8 @@ QDirPrivate::QDirPrivate(const QString &path, const QStringList &nameFilters_, Q
{
setPath(path.isEmpty() ? QString::fromLatin1(".") : path);
- bool empty = nameFilters.isEmpty();
- if (!empty) {
- empty = true;
- for (int i = 0; i < nameFilters.size(); ++i) {
- if (!nameFilters.at(i).isEmpty()) {
- empty = false;
- break;
- }
- }
- }
+ auto isEmpty = [](const auto &e) { return e.isEmpty(); };
+ const bool empty = std::all_of(nameFilters.cbegin(), nameFilters.cend(), isEmpty);
if (empty)
nameFilters = QStringList(QString::fromLatin1("*"));
}
@@ -166,7 +157,7 @@ bool QDirPrivate::exists() const
inline QChar QDirPrivate::getFilterSepChar(const QString &nameFilter)
{
QChar sep(QLatin1Char(';'));
- int i = nameFilter.indexOf(sep, 0);
+ qsizetype i = nameFilter.indexOf(sep, 0);
if (i == -1 && nameFilter.indexOf(QLatin1Char(' '), 0) != -1)
sep = QChar(QLatin1Char(' '));
return sep;
@@ -320,31 +311,31 @@ bool QDirSortItemComparator::operator()(const QDirSortItem &n1, const QDirSortIt
return r < 0;
}
-inline void QDirPrivate::sortFileList(QDir::SortFlags sort, QFileInfoList &l,
+inline void QDirPrivate::sortFileList(QDir::SortFlags sort, const QFileInfoList &l,
QStringList *names, QFileInfoList *infos)
{
// names and infos are always empty lists or 0 here
- int n = l.size();
+ qsizetype n = l.size();
if (n > 0) {
if (n == 1 || (sort & QDir::SortByMask) == QDir::Unsorted) {
if (infos)
*infos = l;
if (names) {
- for (int i = 0; i < n; ++i)
- names->append(l.at(i).fileName());
+ for (const QFileInfo &fi : l)
+ names->append(fi.fileName());
}
} else {
QScopedArrayPointer<QDirSortItem> si(new QDirSortItem[n]);
- for (int i = 0; i < n; ++i)
+ for (qsizetype i = 0; i < n; ++i)
si[i].item = l.at(i);
std::sort(si.data(), si.data() + n, QDirSortItemComparator(sort));
// put them back in the list(s)
if (infos) {
- for (int i = 0; i < n; ++i)
+ for (qsizetype i = 0; i < n; ++i)
infos->append(si[i].item);
}
if (names) {
- for (int i = 0; i < n; ++i)
+ for (qsizetype i = 0; i < n; ++i)
names->append(si[i].item.fileName());
}
}
@@ -713,23 +704,23 @@ QString QDir::dirName() const
#ifdef Q_OS_WIN
-static int drivePrefixLength(const QString &path)
+static qsizetype drivePrefixLength(QStringView path)
{
// Used to extract path's drive for use as prefix for an "absolute except for drive" path
- const int size = path.length();
- int drive = 2; // length of drive prefix
+ const qsizetype size = path.size();
+ qsizetype drive = 2; // length of drive prefix
if (size > 1 && path.at(1).unicode() == ':') {
if (Q_UNLIKELY(!path.at(0).isLetter()))
return 0;
} else if (path.startsWith(QLatin1String("//"))) {
// UNC path; use its //server/share part as "drive" - it's as sane a
// thing as we can do.
- for (int i = 2; i-- > 0; ) { // Scan two "path fragments":
+ for (int i = 0 ; i < 2 ; ++i) { // Scan two "path fragments":
while (drive < size && path.at(drive).unicode() == '/')
drive++;
if (drive >= size) {
qWarning("Base directory starts with neither a drive nor a UNC share: %s",
- qUtf8Printable(QDir::toNativeSeparators(path)));
+ qUtf8Printable(QDir::toNativeSeparators(path.toString())));
return 0;
}
while (drive < size && path.at(drive).unicode() != '/')
@@ -779,7 +770,7 @@ QString QDir::filePath(const QString &fileName) const
#ifdef Q_OS_WIN
if (fileName.startsWith(QLatin1Char('/')) || fileName.startsWith(QLatin1Char('\\'))) {
// Handle the "absolute except for drive" case (i.e. \blah not c:\blah):
- const int drive = drivePrefixLength(ret);
+ const qsizetype drive = drivePrefixLength(ret);
return drive > 0 ? QStringView{ret}.left(drive) % fileName : fileName;
}
#endif // Q_OS_WIN
@@ -811,7 +802,7 @@ QString QDir::absoluteFilePath(const QString &fileName) const
// Handle the "absolute except for drive" case (i.e. \blah not c:\blah):
if (fileName.startsWith(QLatin1Char('/')) || fileName.startsWith(QLatin1Char('\\'))) {
// Combine absoluteDirPath's drive with fileName
- const int drive = drivePrefixLength(absoluteDirPath);
+ const qsizetype drive = drivePrefixLength(absoluteDirPath);
if (Q_LIKELY(drive))
return QStringView{absoluteDirPath}.left(drive) % fileName;
@@ -920,7 +911,7 @@ QString QDir::relativeFilePath(const QString &fileName) const
QString QDir::toNativeSeparators(const QString &pathName)
{
#if defined(Q_OS_WIN)
- int i = pathName.indexOf(QLatin1Char('/'));
+ qsizetype i = pathName.indexOf(u'/');
if (i != -1) {
QString n(pathName);
@@ -1065,7 +1056,17 @@ void QDir::setNameFilters(const QStringList &nameFilters)
d->nameFilters = nameFilters;
}
-#ifdef QT_BUILD_CORE_LIB
+#ifndef QT_BOOTSTRAPPED
+
+namespace {
+struct DirSearchPaths {
+ mutable QReadWriteLock mutex;
+ QHash<QString, QStringList> paths;
+};
+}
+
+Q_GLOBAL_STATIC(DirSearchPaths, dirSearchPaths)
+
/*!
\since 4.3
@@ -1093,19 +1094,19 @@ void QDir::setSearchPaths(const QString &prefix, const QStringList &searchPaths)
return;
}
- for (int i = 0; i < prefix.count(); ++i) {
- if (!prefix.at(i).isLetterOrNumber()) {
+ for (QChar ch : prefix) {
+ if (!ch.isLetterOrNumber()) {
qWarning("QDir::setSearchPaths: Prefix can only contain letters or numbers");
return;
}
}
- QWriteLocker lock(&QCoreGlobalData::instance()->dirSearchPathsLock);
- QMap<QString, QStringList> &paths = QCoreGlobalData::instance()->dirSearchPaths;
+ DirSearchPaths &conf = *dirSearchPaths;
+ const QWriteLocker lock(&conf.mutex);
if (searchPaths.isEmpty()) {
- paths.remove(prefix);
+ conf.paths.remove(prefix);
} else {
- paths.insert(prefix, searchPaths);
+ conf.paths.insert(prefix, searchPaths);
}
}
@@ -1121,8 +1122,9 @@ void QDir::addSearchPath(const QString &prefix, const QString &path)
if (path.isEmpty())
return;
- QWriteLocker lock(&QCoreGlobalData::instance()->dirSearchPathsLock);
- QCoreGlobalData::instance()->dirSearchPaths[prefix] += path;
+ DirSearchPaths &conf = *dirSearchPaths;
+ const QWriteLocker lock(&conf.mutex);
+ conf.paths[prefix] += path;
}
/*!
@@ -1134,11 +1136,15 @@ void QDir::addSearchPath(const QString &prefix, const QString &path)
*/
QStringList QDir::searchPaths(const QString &prefix)
{
- QReadLocker lock(&QCoreGlobalData::instance()->dirSearchPathsLock);
- return QCoreGlobalData::instance()->dirSearchPaths.value(prefix);
+ if (!dirSearchPaths.exists())
+ return QStringList();
+
+ const DirSearchPaths &conf = *dirSearchPaths;
+ const QReadLocker lock(&conf.mutex);
+ return conf.paths.value(prefix);
}
-#endif // QT_BUILD_CORE_LIB
+#endif // QT_BOOTSTRAPPED
/*!
Returns the value set by setFilter()
@@ -2136,7 +2142,7 @@ QString qt_normalizePathSegments(const QString &name, QDirPrivate::PathNormaliza
{
const bool allowUncPaths = flags.testAnyFlag(QDirPrivate::AllowUncPaths);
const bool isRemote = flags.testAnyFlag(QDirPrivate::RemotePath);
- const int len = name.length();
+ const qsizetype len = name.size();
if (ok)
*ok = false;
@@ -2144,15 +2150,15 @@ QString qt_normalizePathSegments(const QString &name, QDirPrivate::PathNormaliza
if (len == 0)
return name;
- int i = len - 1;
+ qsizetype i = len - 1;
QVarLengthArray<char16_t> outVector(len);
- int used = len;
+ qsizetype used = len;
char16_t *out = outVector.data();
const ushort *p = name.utf16();
const ushort *prefix = p;
- int up = 0;
+ qsizetype up = 0;
- const int prefixLength = rootLength(name, allowUncPaths);
+ const qsizetype prefixLength = rootLength(name, allowUncPaths);
p += prefixLength;
i -= prefixLength;
@@ -2163,10 +2169,10 @@ QString qt_normalizePathSegments(const QString &name, QDirPrivate::PathNormaliza
--i;
}
- auto isDot = [](const ushort *p, int i) {
+ auto isDot = [](const ushort *p, qsizetype i) {
return i > 1 && p[i - 1] == '.' && p[i - 2] == '/';
};
- auto isDotDot = [](const ushort *p, int i) {
+ auto isDotDot = [](const ushort *p, qsizetype i) {
return i > 2 && p[i - 1] == '.' && p[i - 2] == '.' && p[i - 3] == '/';
};
@@ -2269,7 +2275,7 @@ QString qt_normalizePathSegments(const QString &name, QDirPrivate::PathNormaliza
// string only consists of a prefix followed by one or more slashes. Just skip the slash.
++used;
}
- for (int i = prefixLength - 1; i >= 0; --i)
+ for (qsizetype i = prefixLength - 1; i >= 0; --i)
out[--used] = prefix[i];
} else {
if (isEmpty) {