forked from qt-creator/qt-creator
make VFS aware of exact vs. cumulative evaluation
the cumulative evaluation has a good chance to make a mess of the virtual file contents created by the exact parsing, so better contain it to its own namespace. the ProFile cache also needs to keep the files separate. this specifically addresses the side issue discussed in QTCREATORBUG-10779. it also fixes attempts to deploy the wrong build when the variant is selected through a cache file, as in QTCREATORBUG-15815. in the project explorer, we don't track from which evaluation pass particular files came from, so we try the cumulative first to get the most contents, and fall back to the exact one if the former file is empty (or does not exist at all). Task-number: QTCREATORBUG-15815 Change-Id: I2c1eb16c97526fa275a1c6a2eae9266d385859ac Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
This commit is contained in:
@@ -581,7 +581,12 @@ struct InternalNode
|
|||||||
foreach (const FileName &file, resourcesToAdd) {
|
foreach (const FileName &file, resourcesToAdd) {
|
||||||
auto vfs = static_cast<QmakePriFileNode *>(folder->projectNode())->m_project->qmakeVfs();
|
auto vfs = static_cast<QmakePriFileNode *>(folder->projectNode())->m_project->qmakeVfs();
|
||||||
QString contents;
|
QString contents;
|
||||||
vfs->readVirtualFile(file.toString(), &contents);
|
// Prefer the cumulative file if it's non-empty, based on the assumption
|
||||||
|
// that it contains more "stuff".
|
||||||
|
vfs->readVirtualFile(file.toString(), QMakeVfs::VfsCumulative, &contents);
|
||||||
|
// If the cumulative evaluation botched the file too much, try the exact one.
|
||||||
|
if (contents.isEmpty())
|
||||||
|
vfs->readVirtualFile(file.toString(), QMakeVfs::VfsExact, &contents);
|
||||||
nodesToAdd.append(new ResourceEditor::ResourceTopLevelNode(file, contents, folder));
|
nodesToAdd.append(new ResourceEditor::ResourceTopLevelNode(file, contents, folder));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1953,10 +1958,10 @@ EvalResult *QmakeProFileNode::evaluate(const EvalInput &input)
|
|||||||
result->newVarValues[HeaderExtensionVar] = QStringList() << input.readerExact->value(QLatin1String("QMAKE_EXT_H"));
|
result->newVarValues[HeaderExtensionVar] = QStringList() << input.readerExact->value(QLatin1String("QMAKE_EXT_H"));
|
||||||
result->newVarValues[CppExtensionVar] = QStringList() << input.readerExact->value(QLatin1String("QMAKE_EXT_CPP"));
|
result->newVarValues[CppExtensionVar] = QStringList() << input.readerExact->value(QLatin1String("QMAKE_EXT_CPP"));
|
||||||
result->newVarValues[MocDirVar] = QStringList() << mocDirPath(input.readerExact, input.buildDirectory);
|
result->newVarValues[MocDirVar] = QStringList() << mocDirPath(input.readerExact, input.buildDirectory);
|
||||||
result->newVarValues[ResourceVar] = fileListForVar(input.readerExact, input.readerCumulative,
|
|
||||||
QLatin1String("RESOURCES"), input.projectDir, input.buildDirectory);
|
|
||||||
result->newVarValues[ExactResourceVar] = fileListForVar(input.readerExact, 0,
|
result->newVarValues[ExactResourceVar] = fileListForVar(input.readerExact, 0,
|
||||||
QLatin1String("RESOURCES"), input.projectDir, input.buildDirectory);
|
QLatin1String("RESOURCES"), input.projectDir, input.buildDirectory);
|
||||||
|
result->newVarValues[CumulativeResourceVar] = fileListForVar(input.readerCumulative, 0,
|
||||||
|
QLatin1String("RESOURCES"), input.projectDir, input.buildDirectory);
|
||||||
result->newVarValues[PkgConfigVar] = input.readerExact->values(QLatin1String("PKGCONFIG"));
|
result->newVarValues[PkgConfigVar] = input.readerExact->values(QLatin1String("PKGCONFIG"));
|
||||||
result->newVarValues[PrecompiledHeaderVar] = input.readerExact->fixifiedValues(
|
result->newVarValues[PrecompiledHeaderVar] = input.readerExact->fixifiedValues(
|
||||||
QLatin1String("PRECOMPILED_HEADER"), input.projectDir, input.buildDirectory);
|
QLatin1String("PRECOMPILED_HEADER"), input.projectDir, input.buildDirectory);
|
||||||
|
@@ -82,8 +82,8 @@ enum QmakeVariable {
|
|||||||
CppSourceVar,
|
CppSourceVar,
|
||||||
ObjCSourceVar,
|
ObjCSourceVar,
|
||||||
ObjCHeaderVar,
|
ObjCHeaderVar,
|
||||||
ResourceVar,
|
|
||||||
ExactResourceVar,
|
ExactResourceVar,
|
||||||
|
CumulativeResourceVar,
|
||||||
UiDirVar,
|
UiDirVar,
|
||||||
HeaderExtensionVar,
|
HeaderExtensionVar,
|
||||||
CppExtensionVar,
|
CppExtensionVar,
|
||||||
|
@@ -564,11 +564,19 @@ void QmakeProject::updateQmlJSCodeModel()
|
|||||||
foreach (const QString &path, node->variableValue(QmlImportPathVar))
|
foreach (const QString &path, node->variableValue(QmlImportPathVar))
|
||||||
projectInfo.importPaths.maybeInsert(FileName::fromString(path),
|
projectInfo.importPaths.maybeInsert(FileName::fromString(path),
|
||||||
QmlJS::Dialect::Qml);
|
QmlJS::Dialect::Qml);
|
||||||
projectInfo.activeResourceFiles.append(node->variableValue(ExactResourceVar));
|
const QStringList &exactResources = node->variableValue(ExactResourceVar);
|
||||||
projectInfo.allResourceFiles.append(node->variableValue(ResourceVar));
|
const QStringList &cumulativeResources = node->variableValue(CumulativeResourceVar);
|
||||||
foreach (const QString &rc, projectInfo.allResourceFiles) {
|
projectInfo.activeResourceFiles.append(exactResources);
|
||||||
|
projectInfo.allResourceFiles.append(exactResources);
|
||||||
|
projectInfo.allResourceFiles.append(cumulativeResources);
|
||||||
|
foreach (const QString &rc, exactResources) {
|
||||||
QString contents;
|
QString contents;
|
||||||
if (m_qmakeVfs->readVirtualFile(rc, &contents))
|
if (m_qmakeVfs->readVirtualFile(rc, QMakeVfs::VfsExact, &contents))
|
||||||
|
projectInfo.resourceFileContents[rc] = contents;
|
||||||
|
}
|
||||||
|
foreach (const QString &rc, cumulativeResources) {
|
||||||
|
QString contents;
|
||||||
|
if (m_qmakeVfs->readVirtualFile(rc, QMakeVfs::VfsCumulative, &contents))
|
||||||
projectInfo.resourceFileContents[rc] = contents;
|
projectInfo.resourceFileContents[rc] = contents;
|
||||||
}
|
}
|
||||||
if (!hasQmlLib) {
|
if (!hasQmlLib) {
|
||||||
|
@@ -12,5 +12,6 @@ DEFINES *= \
|
|||||||
PROPARSER_THREAD_SAFE \
|
PROPARSER_THREAD_SAFE \
|
||||||
PROEVALUATOR_THREAD_SAFE \
|
PROEVALUATOR_THREAD_SAFE \
|
||||||
PROEVALUATOR_CUMULATIVE \
|
PROEVALUATOR_CUMULATIVE \
|
||||||
|
PROEVALUATOR_DUAL_VFS \
|
||||||
PROEVALUATOR_SETENV
|
PROEVALUATOR_SETENV
|
||||||
INCLUDEPATH *= $$PWD/../../shared
|
INCLUDEPATH *= $$PWD/../../shared
|
||||||
|
@@ -123,11 +123,12 @@ QStringList ProFileEvaluator::absoluteFileValues(
|
|||||||
const QString &variable, const QString &baseDirectory, const QStringList &searchDirs,
|
const QString &variable, const QString &baseDirectory, const QStringList &searchDirs,
|
||||||
const ProFile *pro) const
|
const ProFile *pro) const
|
||||||
{
|
{
|
||||||
|
QMakeVfs::VfsFlags flags = (d->m_cumulative ? QMakeVfs::VfsCumulative : QMakeVfs::VfsExact);
|
||||||
QStringList result;
|
QStringList result;
|
||||||
foreach (const QString &el, pro ? values(variable, pro) : values(variable)) {
|
foreach (const QString &el, pro ? values(variable, pro) : values(variable)) {
|
||||||
QString absEl;
|
QString absEl;
|
||||||
if (IoUtils::isAbsolutePath(el)) {
|
if (IoUtils::isAbsolutePath(el)) {
|
||||||
if (m_vfs->exists(el)) {
|
if (m_vfs->exists(el, flags)) {
|
||||||
result << el;
|
result << el;
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
@@ -135,7 +136,7 @@ QStringList ProFileEvaluator::absoluteFileValues(
|
|||||||
} else {
|
} else {
|
||||||
foreach (const QString &dir, searchDirs) {
|
foreach (const QString &dir, searchDirs) {
|
||||||
QString fn = QDir::cleanPath(dir + QLatin1Char('/') + el);
|
QString fn = QDir::cleanPath(dir + QLatin1Char('/') + el);
|
||||||
if (m_vfs->exists(fn)) {
|
if (m_vfs->exists(fn, flags)) {
|
||||||
result << fn;
|
result << fn;
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
|
@@ -414,10 +414,10 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::parseJsonInto(const QByteArray &json
|
|||||||
|
|
||||||
QMakeEvaluator::VisitReturn
|
QMakeEvaluator::VisitReturn
|
||||||
QMakeEvaluator::writeFile(const QString &ctx, const QString &fn, QIODevice::OpenMode mode,
|
QMakeEvaluator::writeFile(const QString &ctx, const QString &fn, QIODevice::OpenMode mode,
|
||||||
bool exe, const QString &contents)
|
QMakeVfs::VfsFlags flags, const QString &contents)
|
||||||
{
|
{
|
||||||
QString errStr;
|
QString errStr;
|
||||||
if (!m_vfs->writeFile(fn, mode, exe, contents, &errStr)) {
|
if (!m_vfs->writeFile(fn, mode, flags, contents, &errStr)) {
|
||||||
evalError(fL1S("Cannot write %1file %2: %3")
|
evalError(fL1S("Cannot write %1file %2: %3")
|
||||||
.arg(ctx, QDir::toNativeSeparators(fn), errStr));
|
.arg(ctx, QDir::toNativeSeparators(fn), errStr));
|
||||||
return ReturnFalse;
|
return ReturnFalse;
|
||||||
@@ -1714,7 +1714,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
|
|||||||
return ReturnFalse;
|
return ReturnFalse;
|
||||||
}
|
}
|
||||||
QIODevice::OpenMode mode = QIODevice::Truncate;
|
QIODevice::OpenMode mode = QIODevice::Truncate;
|
||||||
bool exe = false;
|
QMakeVfs::VfsFlags flags = (m_cumulative ? QMakeVfs::VfsCumulative : QMakeVfs::VfsExact);
|
||||||
QString contents;
|
QString contents;
|
||||||
if (args.count() >= 2) {
|
if (args.count() >= 2) {
|
||||||
const ProStringList &vals = values(args.at(1).toKey());
|
const ProStringList &vals = values(args.at(1).toKey());
|
||||||
@@ -1727,7 +1727,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
|
|||||||
if (m_tmp3 == QLatin1String("append")) {
|
if (m_tmp3 == QLatin1String("append")) {
|
||||||
mode = QIODevice::Append;
|
mode = QIODevice::Append;
|
||||||
} else if (m_tmp3 == QLatin1String("exe")) {
|
} else if (m_tmp3 == QLatin1String("exe")) {
|
||||||
exe = true;
|
flags |= QMakeVfs::VfsExecutable;
|
||||||
} else {
|
} else {
|
||||||
evalError(fL1S("write_file(): invalid flag %1.").arg(m_tmp3));
|
evalError(fL1S("write_file(): invalid flag %1.").arg(m_tmp3));
|
||||||
return ReturnFalse;
|
return ReturnFalse;
|
||||||
@@ -1737,7 +1737,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
|
|||||||
}
|
}
|
||||||
QString path = resolvePath(args.at(0).toQString(m_tmp1));
|
QString path = resolvePath(args.at(0).toQString(m_tmp1));
|
||||||
path.detach(); // make sure to not leak m_tmp1 into the map of written files.
|
path.detach(); // make sure to not leak m_tmp1 into the map of written files.
|
||||||
return writeFile(QString(), path, mode, exe, contents);
|
return writeFile(QString(), path, mode, flags, contents);
|
||||||
}
|
}
|
||||||
case T_TOUCH: {
|
case T_TOUCH: {
|
||||||
if (args.count() != 2) {
|
if (args.count() != 2) {
|
||||||
@@ -1921,6 +1921,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
|
|||||||
varstr += QLatin1Char('\n');
|
varstr += QLatin1Char('\n');
|
||||||
}
|
}
|
||||||
QString fn;
|
QString fn;
|
||||||
|
QMakeVfs::VfsFlags flags = (m_cumulative ? QMakeVfs::VfsCumulative : QMakeVfs::VfsExact);
|
||||||
if (target == TargetSuper) {
|
if (target == TargetSuper) {
|
||||||
if (m_superfile.isEmpty()) {
|
if (m_superfile.isEmpty()) {
|
||||||
m_superfile = QDir::cleanPath(m_outputDir + QLatin1String("/.qmake.super"));
|
m_superfile = QDir::cleanPath(m_outputDir + QLatin1String("/.qmake.super"));
|
||||||
@@ -1944,12 +1945,12 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
|
|||||||
fn = m_stashfile;
|
fn = m_stashfile;
|
||||||
if (fn.isEmpty())
|
if (fn.isEmpty())
|
||||||
fn = QDir::cleanPath(m_outputDir + QLatin1String("/.qmake.stash"));
|
fn = QDir::cleanPath(m_outputDir + QLatin1String("/.qmake.stash"));
|
||||||
if (!m_vfs->exists(fn)) {
|
if (!m_vfs->exists(fn, flags)) {
|
||||||
printf("Info: creating stash file %s\n", qPrintable(QDir::toNativeSeparators(fn)));
|
printf("Info: creating stash file %s\n", qPrintable(QDir::toNativeSeparators(fn)));
|
||||||
valuesRef(ProKey("_QMAKE_STASH_")) << ProString(fn);
|
valuesRef(ProKey("_QMAKE_STASH_")) << ProString(fn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return writeFile(fL1S("cache "), fn, QIODevice::Append, false, varstr);
|
return writeFile(fL1S("cache "), fn, QIODevice::Append, flags, varstr);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
evalError(fL1S("Function '%1' is not implemented.").arg(function.toQString(m_tmp1)));
|
evalError(fL1S("Function '%1' is not implemented.").arg(function.toQString(m_tmp1)));
|
||||||
|
@@ -1082,6 +1082,7 @@ void QMakeEvaluator::loadDefaults()
|
|||||||
|
|
||||||
bool QMakeEvaluator::prepareProject(const QString &inDir)
|
bool QMakeEvaluator::prepareProject(const QString &inDir)
|
||||||
{
|
{
|
||||||
|
QMakeVfs::VfsFlags flags = (m_cumulative ? QMakeVfs::VfsCumulative : QMakeVfs::VfsExact);
|
||||||
QString superdir;
|
QString superdir;
|
||||||
if (m_option->do_cache) {
|
if (m_option->do_cache) {
|
||||||
QString conffile;
|
QString conffile;
|
||||||
@@ -1092,7 +1093,7 @@ bool QMakeEvaluator::prepareProject(const QString &inDir)
|
|||||||
superdir = m_outputDir;
|
superdir = m_outputDir;
|
||||||
forever {
|
forever {
|
||||||
QString superfile = superdir + QLatin1String("/.qmake.super");
|
QString superfile = superdir + QLatin1String("/.qmake.super");
|
||||||
if (m_vfs->exists(superfile)) {
|
if (m_vfs->exists(superfile, flags)) {
|
||||||
m_superfile = QDir::cleanPath(superfile);
|
m_superfile = QDir::cleanPath(superfile);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1107,10 +1108,10 @@ bool QMakeEvaluator::prepareProject(const QString &inDir)
|
|||||||
QString dir = m_outputDir;
|
QString dir = m_outputDir;
|
||||||
forever {
|
forever {
|
||||||
conffile = sdir + QLatin1String("/.qmake.conf");
|
conffile = sdir + QLatin1String("/.qmake.conf");
|
||||||
if (!m_vfs->exists(conffile))
|
if (!m_vfs->exists(conffile, flags))
|
||||||
conffile.clear();
|
conffile.clear();
|
||||||
cachefile = dir + QLatin1String("/.qmake.cache");
|
cachefile = dir + QLatin1String("/.qmake.cache");
|
||||||
if (!m_vfs->exists(cachefile))
|
if (!m_vfs->exists(cachefile, flags))
|
||||||
cachefile.clear();
|
cachefile.clear();
|
||||||
if (!conffile.isEmpty() || !cachefile.isEmpty()) {
|
if (!conffile.isEmpty() || !cachefile.isEmpty()) {
|
||||||
if (dir != sdir)
|
if (dir != sdir)
|
||||||
@@ -1138,7 +1139,7 @@ bool QMakeEvaluator::prepareProject(const QString &inDir)
|
|||||||
QString dir = m_outputDir;
|
QString dir = m_outputDir;
|
||||||
forever {
|
forever {
|
||||||
QString stashfile = dir + QLatin1String("/.qmake.stash");
|
QString stashfile = dir + QLatin1String("/.qmake.stash");
|
||||||
if (dir == (!superdir.isEmpty() ? superdir : m_buildRoot) || m_vfs->exists(stashfile)) {
|
if (dir == (!superdir.isEmpty() ? superdir : m_buildRoot) || m_vfs->exists(stashfile, flags)) {
|
||||||
m_stashfile = QDir::cleanPath(stashfile);
|
m_stashfile = QDir::cleanPath(stashfile);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1265,7 +1266,8 @@ bool QMakeEvaluator::loadSpec()
|
|||||||
m_cachefile, QMakeHandler::EvalConfigFile, LoadProOnly) != ReturnTrue)
|
m_cachefile, QMakeHandler::EvalConfigFile, LoadProOnly) != ReturnTrue)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!m_stashfile.isEmpty() && m_vfs->exists(m_stashfile)) {
|
QMakeVfs::VfsFlags flags = (m_cumulative ? QMakeVfs::VfsCumulative : QMakeVfs::VfsExact);
|
||||||
|
if (!m_stashfile.isEmpty() && m_vfs->exists(m_stashfile, flags)) {
|
||||||
valuesRef(ProKey("_QMAKE_STASH_")) << ProString(m_stashfile);
|
valuesRef(ProKey("_QMAKE_STASH_")) << ProString(m_stashfile);
|
||||||
if (evaluateFile(
|
if (evaluateFile(
|
||||||
m_stashfile, QMakeHandler::EvalConfigFile, LoadProOnly) != ReturnTrue)
|
m_stashfile, QMakeHandler::EvalConfigFile, LoadProOnly) != ReturnTrue)
|
||||||
|
@@ -30,6 +30,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "qmakeparser.h"
|
#include "qmakeparser.h"
|
||||||
|
#include "qmakevfs.h"
|
||||||
#include "ioutils.h"
|
#include "ioutils.h"
|
||||||
|
|
||||||
#include <qlist.h>
|
#include <qlist.h>
|
||||||
@@ -232,7 +233,7 @@ public:
|
|||||||
VisitReturn parseJsonInto(const QByteArray &json, const QString &into, ProValueMap *value);
|
VisitReturn parseJsonInto(const QByteArray &json, const QString &into, ProValueMap *value);
|
||||||
|
|
||||||
VisitReturn writeFile(const QString &ctx, const QString &fn, QIODevice::OpenMode mode,
|
VisitReturn writeFile(const QString &ctx, const QString &fn, QIODevice::OpenMode mode,
|
||||||
bool exe, const QString &contents);
|
QMakeVfs::VfsFlags flags, const QString &contents);
|
||||||
#ifndef QT_BOOTSTRAPPED
|
#ifndef QT_BOOTSTRAPPED
|
||||||
void runProcess(QProcess *proc, const QString &command) const;
|
void runProcess(QProcess *proc, const QString &command) const;
|
||||||
#endif
|
#endif
|
||||||
|
@@ -167,7 +167,13 @@ ProFile *QMakeParser::parsedProFile(const QString &fileName, ParseFlags flags)
|
|||||||
#ifdef PROPARSER_THREAD_SAFE
|
#ifdef PROPARSER_THREAD_SAFE
|
||||||
QMutexLocker locker(&m_cache->mutex);
|
QMutexLocker locker(&m_cache->mutex);
|
||||||
#endif
|
#endif
|
||||||
QHash<QString, ProFileCache::Entry>::Iterator it = m_cache->parsed_files.find(fileName);
|
QHash<QString, ProFileCache::Entry>::Iterator it;
|
||||||
|
#ifdef PROEVALUATOR_DUAL_VFS
|
||||||
|
QString virtFileName = ((flags & ParseCumulative) ? '-' : '+') + fileName;
|
||||||
|
it = m_cache->parsed_files.find(virtFileName);
|
||||||
|
if (it == m_cache->parsed_files.end())
|
||||||
|
#endif
|
||||||
|
it = m_cache->parsed_files.find(fileName);
|
||||||
if (it != m_cache->parsed_files.end()) {
|
if (it != m_cache->parsed_files.end()) {
|
||||||
ent = &*it;
|
ent = &*it;
|
||||||
#ifdef PROPARSER_THREAD_SAFE
|
#ifdef PROPARSER_THREAD_SAFE
|
||||||
@@ -185,18 +191,27 @@ ProFile *QMakeParser::parsedProFile(const QString &fileName, ParseFlags flags)
|
|||||||
if ((pro = ent->pro))
|
if ((pro = ent->pro))
|
||||||
pro->ref();
|
pro->ref();
|
||||||
} else if (!(flags & ParseOnlyCached)) {
|
} else if (!(flags & ParseOnlyCached)) {
|
||||||
|
QString contents;
|
||||||
|
QMakeVfs::VfsFlags vfsFlags =
|
||||||
|
((flags & ParseCumulative) ? QMakeVfs::VfsCumulative : QMakeVfs::VfsExact);
|
||||||
|
bool virt = false;
|
||||||
|
#ifdef PROEVALUATOR_DUAL_VFS
|
||||||
|
virt = m_vfs->readVirtualFile(fileName, vfsFlags, &contents);
|
||||||
|
if (virt)
|
||||||
|
ent = &m_cache->parsed_files[virtFileName];
|
||||||
|
else
|
||||||
|
#endif
|
||||||
ent = &m_cache->parsed_files[fileName];
|
ent = &m_cache->parsed_files[fileName];
|
||||||
#ifdef PROPARSER_THREAD_SAFE
|
#ifdef PROPARSER_THREAD_SAFE
|
||||||
ent->locker = new ProFileCache::Entry::Locker;
|
ent->locker = new ProFileCache::Entry::Locker;
|
||||||
locker.unlock();
|
locker.unlock();
|
||||||
#endif
|
#endif
|
||||||
pro = new ProFile(fileName);
|
if (virt || readFile(fileName, vfsFlags | QMakeVfs::VfsNoVirtual, flags, &contents)) {
|
||||||
if (!read(pro, flags)) {
|
pro = parsedProBlock(QStringRef(&contents), fileName, 1, FullGrammar);
|
||||||
delete pro;
|
|
||||||
pro = 0;
|
|
||||||
} else {
|
|
||||||
pro->itemsRef()->squeeze();
|
pro->itemsRef()->squeeze();
|
||||||
pro->ref();
|
pro->ref();
|
||||||
|
} else {
|
||||||
|
pro = 0;
|
||||||
}
|
}
|
||||||
ent->pro = pro;
|
ent->pro = pro;
|
||||||
#ifdef PROPARSER_THREAD_SAFE
|
#ifdef PROPARSER_THREAD_SAFE
|
||||||
@@ -213,11 +228,13 @@ ProFile *QMakeParser::parsedProFile(const QString &fileName, ParseFlags flags)
|
|||||||
pro = 0;
|
pro = 0;
|
||||||
}
|
}
|
||||||
} else if (!(flags & ParseOnlyCached)) {
|
} else if (!(flags & ParseOnlyCached)) {
|
||||||
pro = new ProFile(fileName);
|
QString contents;
|
||||||
if (!read(pro, flags)) {
|
QMakeVfs::VfsFlags vfsFlags =
|
||||||
delete pro;
|
((flags & ParseCumulative) ? QMakeVfs::VfsCumulative : QMakeVfs::VfsExact);
|
||||||
|
if (readFile(fileName, vfsFlags, flags, &contents))
|
||||||
|
pro = parsedProBlock(QStringRef(&contents), fileName, 1, FullGrammar);
|
||||||
|
else
|
||||||
pro = 0;
|
pro = 0;
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
pro = 0;
|
pro = 0;
|
||||||
}
|
}
|
||||||
@@ -238,18 +255,17 @@ void QMakeParser::discardFileFromCache(const QString &fileName)
|
|||||||
m_cache->discardFile(fileName);
|
m_cache->discardFile(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QMakeParser::read(ProFile *pro, ParseFlags flags)
|
bool QMakeParser::readFile(
|
||||||
|
const QString &fn, QMakeVfs::VfsFlags vfsFlags, ParseFlags flags, QString *contents)
|
||||||
{
|
{
|
||||||
QString content;
|
|
||||||
QString errStr;
|
QString errStr;
|
||||||
QMakeVfs::ReadResult result = m_vfs->readFile(pro->fileName(), &content, &errStr);
|
QMakeVfs::ReadResult result = m_vfs->readFile(fn, vfsFlags, contents, &errStr);
|
||||||
if (result != QMakeVfs::ReadOk) {
|
if (result != QMakeVfs::ReadOk) {
|
||||||
if (m_handler && ((flags & ParseReportMissing) || result != QMakeVfs::ReadNotFound))
|
if (m_handler && ((flags & ParseReportMissing) || result != QMakeVfs::ReadNotFound))
|
||||||
m_handler->message(QMakeParserHandler::ParserIoError,
|
m_handler->message(QMakeParserHandler::ParserIoError,
|
||||||
fL1S("Cannot read %1: %2").arg(pro->fileName(), errStr));
|
fL1S("Cannot read %1: %2").arg(fn, errStr));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
read(pro, QStringRef(&content), 1, FullGrammar);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -26,6 +26,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "qmake_global.h"
|
#include "qmake_global.h"
|
||||||
|
#include "qmakevfs.h"
|
||||||
#include "proitems.h"
|
#include "proitems.h"
|
||||||
|
|
||||||
#include <qhash.h>
|
#include <qhash.h>
|
||||||
@@ -75,7 +76,12 @@ public:
|
|||||||
ParseDefault = 0,
|
ParseDefault = 0,
|
||||||
ParseUseCache = 1,
|
ParseUseCache = 1,
|
||||||
ParseOnlyCached = 2,
|
ParseOnlyCached = 2,
|
||||||
ParseReportMissing = 4
|
ParseReportMissing = 4,
|
||||||
|
#ifdef PROEVALUATOR_DUAL_VFS
|
||||||
|
ParseCumulative = 8
|
||||||
|
#else
|
||||||
|
ParseCumulative = 0
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS(ParseFlags, ParseFlag)
|
Q_DECLARE_FLAGS(ParseFlags, ParseFlag)
|
||||||
|
|
||||||
@@ -126,7 +132,7 @@ private:
|
|||||||
ushort terminator; // '}' if replace function call is braced, ':' if test function
|
ushort terminator; // '}' if replace function call is braced, ':' if test function
|
||||||
};
|
};
|
||||||
|
|
||||||
bool read(ProFile *pro, ParseFlags flags);
|
bool readFile(const QString &fn, QMakeVfs::VfsFlags vfsFlags, QMakeParser::ParseFlags flags, QString *contents);
|
||||||
void read(ProFile *pro, const QStringRef &content, int line, SubGrammar grammar);
|
void read(ProFile *pro, const QStringRef &content, int line, SubGrammar grammar);
|
||||||
|
|
||||||
ALWAYS_INLINE void putTok(ushort *&tokPtr, ushort tok);
|
ALWAYS_INLINE void putTok(ushort *&tokPtr, ushort tok);
|
||||||
|
@@ -44,20 +44,24 @@ QMakeVfs::QMakeVfs()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QMakeVfs::writeFile(const QString &fn, QIODevice::OpenMode mode, bool exe,
|
bool QMakeVfs::writeFile(const QString &fn, QIODevice::OpenMode mode, VfsFlags flags,
|
||||||
const QString &contents, QString *errStr)
|
const QString &contents, QString *errStr)
|
||||||
{
|
{
|
||||||
#ifndef PROEVALUATOR_FULL
|
#ifndef PROEVALUATOR_FULL
|
||||||
# ifdef PROEVALUATOR_THREAD_SAFE
|
# ifdef PROEVALUATOR_THREAD_SAFE
|
||||||
QMutexLocker locker(&m_mutex);
|
QMutexLocker locker(&m_mutex);
|
||||||
# endif
|
# endif
|
||||||
|
#ifdef PROEVALUATOR_DUAL_VFS
|
||||||
|
QString *cont = &m_files[((flags & VfsCumulative) ? '-' : '+') + fn];
|
||||||
|
#else
|
||||||
QString *cont = &m_files[fn];
|
QString *cont = &m_files[fn];
|
||||||
|
Q_UNUSED(flags)
|
||||||
|
#endif
|
||||||
if (mode & QIODevice::Append)
|
if (mode & QIODevice::Append)
|
||||||
*cont += contents;
|
*cont += contents;
|
||||||
else
|
else
|
||||||
*cont = contents;
|
*cont = contents;
|
||||||
Q_UNUSED(errStr)
|
Q_UNUSED(errStr)
|
||||||
Q_UNUSED(exe)
|
|
||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
QFileInfo qfi(fn);
|
QFileInfo qfi(fn);
|
||||||
@@ -69,7 +73,7 @@ bool QMakeVfs::writeFile(const QString &fn, QIODevice::OpenMode mode, bool exe,
|
|||||||
QFile cfile(fn);
|
QFile cfile(fn);
|
||||||
if (!(mode & QIODevice::Append) && cfile.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
if (!(mode & QIODevice::Append) && cfile.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||||
if (cfile.readAll() == bytes) {
|
if (cfile.readAll() == bytes) {
|
||||||
if (exe) {
|
if (flags & VfsExecutable) {
|
||||||
cfile.setPermissions(cfile.permissions()
|
cfile.setPermissions(cfile.permissions()
|
||||||
| QFile::ExeUser | QFile::ExeGroup | QFile::ExeOther);
|
| QFile::ExeUser | QFile::ExeGroup | QFile::ExeOther);
|
||||||
} else {
|
} else {
|
||||||
@@ -90,7 +94,7 @@ bool QMakeVfs::writeFile(const QString &fn, QIODevice::OpenMode mode, bool exe,
|
|||||||
*errStr = cfile.errorString();
|
*errStr = cfile.errorString();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (exe)
|
if (flags & VfsExecutable)
|
||||||
cfile.setPermissions(cfile.permissions()
|
cfile.setPermissions(cfile.permissions()
|
||||||
| QFile::ExeUser | QFile::ExeGroup | QFile::ExeOther);
|
| QFile::ExeUser | QFile::ExeGroup | QFile::ExeOther);
|
||||||
return true;
|
return true;
|
||||||
@@ -98,29 +102,52 @@ bool QMakeVfs::writeFile(const QString &fn, QIODevice::OpenMode mode, bool exe,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef PROEVALUATOR_FULL
|
#ifndef PROEVALUATOR_FULL
|
||||||
bool QMakeVfs::readVirtualFile(const QString &fn, QString *contents)
|
bool QMakeVfs::readVirtualFile(const QString &fn, VfsFlags flags, QString *contents)
|
||||||
{
|
{
|
||||||
# ifdef PROEVALUATOR_THREAD_SAFE
|
# ifdef PROEVALUATOR_THREAD_SAFE
|
||||||
QMutexLocker locker(&m_mutex);
|
QMutexLocker locker(&m_mutex);
|
||||||
# endif
|
# endif
|
||||||
QHash<QString, QString>::ConstIterator it = m_files.constFind(fn);
|
QHash<QString, QString>::ConstIterator it;
|
||||||
|
# ifdef PROEVALUATOR_DUAL_VFS
|
||||||
|
it = m_files.constFind(((flags & VfsCumulative) ? '-' : '+') + fn);
|
||||||
|
if (it != m_files.constEnd()) {
|
||||||
|
*contents = *it;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
# else
|
||||||
|
it = m_files.constFind(fn);
|
||||||
if (it != m_files.constEnd()
|
if (it != m_files.constEnd()
|
||||||
&& it->constData() != m_magicMissing.constData()
|
&& it->constData() != m_magicMissing.constData()
|
||||||
&& it->constData() != m_magicExisting.constData()) {
|
&& it->constData() != m_magicExisting.constData()) {
|
||||||
*contents = *it;
|
*contents = *it;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Q_UNUSED(flags)
|
||||||
|
# endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QMakeVfs::ReadResult QMakeVfs::readFile(const QString &fn, QString *contents, QString *errStr)
|
QMakeVfs::ReadResult QMakeVfs::readFile(
|
||||||
|
const QString &fn, VfsFlags flags, QString *contents, QString *errStr)
|
||||||
{
|
{
|
||||||
#ifndef PROEVALUATOR_FULL
|
#ifndef PROEVALUATOR_FULL
|
||||||
# ifdef PROEVALUATOR_THREAD_SAFE
|
# ifdef PROEVALUATOR_THREAD_SAFE
|
||||||
QMutexLocker locker(&m_mutex);
|
QMutexLocker locker(&m_mutex);
|
||||||
# endif
|
# endif
|
||||||
QHash<QString, QString>::ConstIterator it = m_files.constFind(fn);
|
QHash<QString, QString>::ConstIterator it;
|
||||||
|
# ifdef PROEVALUATOR_DUAL_VFS
|
||||||
|
if (!(flags & VfsNoVirtual)) {
|
||||||
|
it = m_files.constFind(((flags & VfsCumulative) ? '-' : '+') + fn);
|
||||||
|
if (it != m_files.constEnd()) {
|
||||||
|
*contents = *it;
|
||||||
|
return ReadOk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# else
|
||||||
|
Q_UNUSED(flags)
|
||||||
|
# endif
|
||||||
|
it = m_files.constFind(fn);
|
||||||
if (it != m_files.constEnd()) {
|
if (it != m_files.constEnd()) {
|
||||||
if (it->constData() == m_magicMissing.constData()) {
|
if (it->constData() == m_magicMissing.constData()) {
|
||||||
*errStr = fL1S("No such file or directory");
|
*errStr = fL1S("No such file or directory");
|
||||||
@@ -131,6 +158,8 @@ QMakeVfs::ReadResult QMakeVfs::readFile(const QString &fn, QString *contents, QS
|
|||||||
return ReadOk;
|
return ReadOk;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
Q_UNUSED(flags)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QFile file(fn);
|
QFile file(fn);
|
||||||
@@ -159,15 +188,25 @@ QMakeVfs::ReadResult QMakeVfs::readFile(const QString &fn, QString *contents, QS
|
|||||||
return ReadOk;
|
return ReadOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QMakeVfs::exists(const QString &fn)
|
bool QMakeVfs::exists(const QString &fn, VfsFlags flags)
|
||||||
{
|
{
|
||||||
#ifndef PROEVALUATOR_FULL
|
#ifndef PROEVALUATOR_FULL
|
||||||
# ifdef PROEVALUATOR_THREAD_SAFE
|
# ifdef PROEVALUATOR_THREAD_SAFE
|
||||||
QMutexLocker locker(&m_mutex);
|
QMutexLocker locker(&m_mutex);
|
||||||
# endif
|
# endif
|
||||||
QHash<QString, QString>::ConstIterator it = m_files.constFind(fn);
|
QHash<QString, QString>::ConstIterator it;
|
||||||
|
# ifdef PROEVALUATOR_DUAL_VFS
|
||||||
|
it = m_files.constFind(((flags & VfsCumulative) ? '-' : '+') + fn);
|
||||||
|
if (it != m_files.constEnd())
|
||||||
|
return true;
|
||||||
|
# else
|
||||||
|
Q_UNUSED(flags)
|
||||||
|
# endif
|
||||||
|
it = m_files.constFind(fn);
|
||||||
if (it != m_files.constEnd())
|
if (it != m_files.constEnd())
|
||||||
return it->constData() != m_magicMissing.constData();
|
return it->constData() != m_magicMissing.constData();
|
||||||
|
#else
|
||||||
|
Q_UNUSED(flags)
|
||||||
#endif
|
#endif
|
||||||
bool ex = IoUtils::fileType(fn) == IoUtils::FileIsRegular;
|
bool ex = IoUtils::fileType(fn) == IoUtils::FileIsRegular;
|
||||||
#ifndef PROEVALUATOR_FULL
|
#ifndef PROEVALUATOR_FULL
|
||||||
|
@@ -36,6 +36,12 @@
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef PROEVALUATOR_DUAL_VFS
|
||||||
|
# ifndef PROEVALUATOR_CUMULATIVE
|
||||||
|
# error PROEVALUATOR_DUAL_VFS requires PROEVALUATOR_CUMULATIVE
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class QMAKE_EXPORT QMakeVfs
|
class QMAKE_EXPORT QMakeVfs
|
||||||
@@ -47,14 +53,27 @@ public:
|
|||||||
ReadOtherError
|
ReadOtherError
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum VfsFlag {
|
||||||
|
VfsExecutable = 1,
|
||||||
|
VfsExact = 0,
|
||||||
|
#ifdef PROEVALUATOR_DUAL_VFS
|
||||||
|
VfsCumulative = 2,
|
||||||
|
VfsNoVirtual = 4
|
||||||
|
#else
|
||||||
|
VfsCumulative = 0,
|
||||||
|
VfsNoVirtual = 0
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
Q_DECLARE_FLAGS(VfsFlags, VfsFlag)
|
||||||
|
|
||||||
QMakeVfs();
|
QMakeVfs();
|
||||||
|
|
||||||
bool writeFile(const QString &fn, QIODevice::OpenMode mode, bool exe, const QString &contents, QString *errStr);
|
bool writeFile(const QString &fn, QIODevice::OpenMode mode, VfsFlags flags, const QString &contents, QString *errStr);
|
||||||
ReadResult readFile(const QString &fn, QString *contents, QString *errStr);
|
ReadResult readFile(const QString &fn, VfsFlags flags, QString *contents, QString *errStr);
|
||||||
bool exists(const QString &fn);
|
bool exists(const QString &fn, VfsFlags flags);
|
||||||
|
|
||||||
#ifndef PROEVALUATOR_FULL
|
#ifndef PROEVALUATOR_FULL
|
||||||
bool readVirtualFile(const QString &fn, QString *contents);
|
bool readVirtualFile(const QString &fn, VfsFlags flags, QString *contents);
|
||||||
|
|
||||||
void invalidateCache();
|
void invalidateCache();
|
||||||
void invalidateContents();
|
void invalidateContents();
|
||||||
@@ -71,4 +90,6 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_OPERATORS_FOR_FLAGS(QMakeVfs::VfsFlags)
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
Reference in New Issue
Block a user