summaryrefslogtreecommitdiffstats
path: root/qmake/library/qmakevfs.cpp
diff options
context:
space:
mode:
authorOswald Buddenhagen <oswald.buddenhagen@qt.io>2016-10-24 19:30:24 +0200
committerOswald Buddenhagen <oswald.buddenhagen@qt.io>2018-03-29 18:15:10 +0000
commite5d909d6d68055c057bbaeadb8f7a4078e6d54e8 (patch)
treea831fcbcac73461a21230c93b3e8613ae090ed53 /qmake/library/qmakevfs.cpp
parent811118f68df4171268f65fa6fc075d6c7633f1e4 (diff)
qmake: make VFS aware of exact vs. cumulative evaluation
sync-up with qt-creator; no effect on qmake. comment on cherry-pick: this is actually a lot more than a cherry-pick, because the dual VFS needs to deal with the file ids which were concurrently introduced on the qmake side. Change-Id: I2c1eb16c97526fa275a1c6a2eae9266d385859ac (cherry picked from qtcreator/424639ecac9d2e404d2bfaff7f46b45ed98664b8) (cherry picked from qtcreator/a8010b0fff47d903d4a1f80e3adb1a2ef41beb33) Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Diffstat (limited to 'qmake/library/qmakevfs.cpp')
-rw-r--r--qmake/library/qmakevfs.cpp105
1 files changed, 89 insertions, 16 deletions
diff --git a/qmake/library/qmakevfs.cpp b/qmake/library/qmakevfs.cpp
index c40f49c4ad..16e21395ba 100644
--- a/qmake/library/qmakevfs.cpp
+++ b/qmake/library/qmakevfs.cpp
@@ -47,32 +47,102 @@ QMakeVfs::QMakeVfs()
{
}
-bool QMakeVfs::writeFile(const QString &fn, QIODevice::OpenMode mode, bool exe,
+#ifdef PROPARSER_THREAD_SAFE
+QMutex QMakeVfs::s_mutex;
+#endif
+QAtomicInt QMakeVfs::s_fileIdCounter;
+QHash<QString, int> QMakeVfs::s_fileIdMap;
+QHash<int, QString> QMakeVfs::s_idFileMap;
+
+int QMakeVfs::idForFileName(const QString &fn, VfsFlags flags)
+{
+#ifdef PROEVALUATOR_DUAL_VFS
+ {
+# ifdef PROPARSER_THREAD_SAFE
+ QMutexLocker locker(&m_vmutex);
+# endif
+ int idx = (flags & VfsCumulative) ? 1 : 0;
+ if (flags & VfsCreate) {
+ int &id = m_virtualFileIdMap[idx][fn];
+ if (!id) {
+ id = ++s_fileIdCounter;
+ m_virtualIdFileMap[id] = fn;
+ }
+ return id;
+ }
+ int id = m_virtualFileIdMap[idx].value(fn);
+ if (id || (flags & VfsCreatedOnly))
+ return id;
+ }
+#endif
+ if (!(flags & VfsAccessedOnly)) {
+#ifdef PROPARSER_THREAD_SAFE
+ QMutexLocker locker(&s_mutex);
+#endif
+ int &id = s_fileIdMap[fn];
+ if (!id) {
+ id = ++s_fileIdCounter;
+ s_idFileMap[id] = fn;
+ }
+ return id;
+ }
+ return s_fileIdMap.value(fn);
+}
+
+QString QMakeVfs::fileNameForId(int id)
+{
+#ifdef PROEVALUATOR_DUAL_VFS
+ {
+# ifdef PROPARSER_THREAD_SAFE
+ QMutexLocker locker(&m_vmutex);
+# endif
+ const QString &fn = m_virtualIdFileMap.value(id);
+ if (!fn.isEmpty())
+ return fn;
+ }
+#endif
+#ifdef PROPARSER_THREAD_SAFE
+ QMutexLocker locker(&s_mutex);
+#endif
+ return s_idFileMap.value(id);
+}
+
+void QMakeVfs::clearIds()
+{
+#ifdef PROEVALUATOR_THREAD_SAFE
+ QMutexLocker locker(&s_mutex);
+#endif
+ s_fileIdCounter = 0;
+ s_fileIdMap.clear();
+ s_idFileMap.clear();
+}
+
+bool QMakeVfs::writeFile(int id, QIODevice::OpenMode mode, VfsFlags flags,
const QString &contents, QString *errStr)
{
#ifndef PROEVALUATOR_FULL
# ifdef PROEVALUATOR_THREAD_SAFE
QMutexLocker locker(&m_mutex);
# endif
- QString *cont = &m_files[fn];
+ QString *cont = &m_files[id];
+ Q_UNUSED(flags)
if (mode & QIODevice::Append)
*cont += contents;
else
*cont = contents;
Q_UNUSED(errStr)
- Q_UNUSED(exe)
return true;
#else
- QFileInfo qfi(fn);
+ QFileInfo qfi(fileNameForId(id));
if (!QDir::current().mkpath(qfi.path())) {
*errStr = fL1S("Cannot create parent directory");
return false;
}
QByteArray bytes = contents.toLocal8Bit();
- QFile cfile(fn);
+ QFile cfile(qfi.filePath());
if (!(mode & QIODevice::Append) && cfile.open(QIODevice::ReadOnly | QIODevice::Text)) {
if (cfile.readAll() == bytes) {
- if (exe) {
+ if (flags & VfsExecutable) {
cfile.setPermissions(cfile.permissions()
| QFile::ExeUser | QFile::ExeGroup | QFile::ExeOther);
} else {
@@ -93,20 +163,20 @@ bool QMakeVfs::writeFile(const QString &fn, QIODevice::OpenMode mode, bool exe,
*errStr = cfile.errorString();
return false;
}
- if (exe)
+ if (flags & VfsExecutable)
cfile.setPermissions(cfile.permissions()
| QFile::ExeUser | QFile::ExeGroup | QFile::ExeOther);
return true;
#endif
}
-QMakeVfs::ReadResult QMakeVfs::readFile(const QString &fn, QString *contents, QString *errStr)
+QMakeVfs::ReadResult QMakeVfs::readFile(int id, QString *contents, QString *errStr)
{
#ifndef PROEVALUATOR_FULL
# ifdef PROEVALUATOR_THREAD_SAFE
QMutexLocker locker(&m_mutex);
# endif
- QHash<QString, QString>::ConstIterator it = m_files.constFind(fn);
+ auto it = m_files.constFind(id);
if (it != m_files.constEnd()) {
if (it->constData() == m_magicMissing.constData()) {
*errStr = fL1S("No such file or directory");
@@ -119,11 +189,11 @@ QMakeVfs::ReadResult QMakeVfs::readFile(const QString &fn, QString *contents, QS
}
#endif
- QFile file(fn);
+ QFile file(fileNameForId(id));
if (!file.open(QIODevice::ReadOnly)) {
if (!file.exists()) {
#ifndef PROEVALUATOR_FULL
- m_files[fn] = m_magicMissing;
+ m_files[id] = m_magicMissing;
#endif
*errStr = fL1S("No such file or directory");
return ReadNotFound;
@@ -132,7 +202,7 @@ QMakeVfs::ReadResult QMakeVfs::readFile(const QString &fn, QString *contents, QS
return ReadOtherError;
}
#ifndef PROEVALUATOR_FULL
- m_files[fn] = m_magicExisting;
+ m_files[id] = m_magicExisting;
#endif
QByteArray bcont = file.readAll();
@@ -145,19 +215,22 @@ QMakeVfs::ReadResult QMakeVfs::readFile(const QString &fn, QString *contents, QS
return ReadOk;
}
-bool QMakeVfs::exists(const QString &fn)
+bool QMakeVfs::exists(const QString &fn, VfsFlags flags)
{
#ifndef PROEVALUATOR_FULL
# ifdef PROEVALUATOR_THREAD_SAFE
QMutexLocker locker(&m_mutex);
# endif
- QHash<QString, QString>::ConstIterator it = m_files.constFind(fn);
+ int id = idForFileName(fn, flags);
+ auto it = m_files.constFind(id);
if (it != m_files.constEnd())
return it->constData() != m_magicMissing.constData();
+#else
+ Q_UNUSED(flags)
#endif
bool ex = IoUtils::fileType(fn) == IoUtils::FileIsRegular;
#ifndef PROEVALUATOR_FULL
- m_files[fn] = ex ? m_magicExisting : m_magicMissing;
+ m_files[id] = ex ? m_magicExisting : m_magicMissing;
#endif
return ex;
}
@@ -169,7 +242,7 @@ void QMakeVfs::invalidateCache()
# ifdef PROEVALUATOR_THREAD_SAFE
QMutexLocker locker(&m_mutex);
# endif
- QHash<QString, QString>::Iterator it = m_files.begin(), eit = m_files.end();
+ auto it = m_files.begin(), eit = m_files.end();
while (it != eit) {
if (it->constData() == m_magicMissing.constData()
||it->constData() == m_magicExisting.constData())