forked from qt-creator/qt-creator
qmake: Change source identifier type in ProString
The strings remember in which file they were created/assigned. However, this used a non-counting reference to a ProFile, which could become dangling. If a subsequent ProFile re-used the exact same address, a string's source would be mis-identified, which would be fatal in conjunction with discard_from(). Since we actually need only a unique id for comparison, let's use an integer for that. comment on cherry-pick: this is actually a lot more than a cherry-pick, because the file ids need to be aware of the dual VFS which was concurrently introduced on the qtc side. Started-by: Simon Hausmann <simon.hausmann@qt.io> Change-Id: I395153afaf7c835d0119690ee7f4b915e6f90d4a (cherry picked from qtbase/190aa94be7f5e146bef44862b974d733755cec85) Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
This commit is contained in:
@@ -160,10 +160,13 @@ static void createTree(const QmakePriFile *pri, QmakePriFileNode *node, const Fi
|
|||||||
QString errorMessage;
|
QString errorMessage;
|
||||||
// Prefer the cumulative file if it's non-empty, based on the assumption
|
// Prefer the cumulative file if it's non-empty, based on the assumption
|
||||||
// that it contains more "stuff".
|
// that it contains more "stuff".
|
||||||
vfs->readFile(file.toString(), QMakeVfs::VfsCumulative, &contents, &errorMessage);
|
int cid = vfs->idForFileName(file.toString(), QMakeVfs::VfsCumulative);
|
||||||
|
vfs->readFile(cid, &contents, &errorMessage);
|
||||||
// If the cumulative evaluation botched the file too much, try the exact one.
|
// If the cumulative evaluation botched the file too much, try the exact one.
|
||||||
if (contents.isEmpty())
|
if (contents.isEmpty()) {
|
||||||
vfs->readFile(file.toString(), QMakeVfs::VfsExact, &contents, &errorMessage);
|
int eid = vfs->idForFileName(file.toString(), QMakeVfs::VfsExact);
|
||||||
|
vfs->readFile(eid, &contents, &errorMessage);
|
||||||
|
}
|
||||||
auto resourceNode = new ResourceEditor::ResourceTopLevelNode(file, false, contents, vfolder);
|
auto resourceNode = new ResourceEditor::ResourceTopLevelNode(file, false, contents, vfolder);
|
||||||
vfolder->addNode(resourceNode);
|
vfolder->addNode(resourceNode);
|
||||||
}
|
}
|
||||||
|
@@ -237,7 +237,8 @@ QmakePriFile::~QmakePriFile()
|
|||||||
|
|
||||||
void QmakePriFile::scheduleUpdate()
|
void QmakePriFile::scheduleUpdate()
|
||||||
{
|
{
|
||||||
QtSupport::ProFileCacheManager::instance()->discardFile(filePath().toString());
|
QtSupport::ProFileCacheManager::instance()->discardFile(
|
||||||
|
filePath().toString(), m_project->qmakeVfs());
|
||||||
m_qmakeProFile->scheduleUpdate(QmakeProFile::ParseLater);
|
m_qmakeProFile->scheduleUpdate(QmakeProFile::ParseLater);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,11 +293,11 @@ static QStringList fileListForVar(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void QmakePriFile::extractSources(
|
void QmakePriFile::extractSources(
|
||||||
QHash<const ProFile *, QmakePriFileEvalResult *> proToResult, QmakePriFileEvalResult *fallback,
|
QHash<int, QmakePriFileEvalResult *> proToResult, QmakePriFileEvalResult *fallback,
|
||||||
QVector<ProFileEvaluator::SourceFile> sourceFiles, FileType type)
|
QVector<ProFileEvaluator::SourceFile> sourceFiles, FileType type)
|
||||||
{
|
{
|
||||||
foreach (const ProFileEvaluator::SourceFile &source, sourceFiles) {
|
foreach (const ProFileEvaluator::SourceFile &source, sourceFiles) {
|
||||||
QmakePriFileEvalResult *result = proToResult.value(source.proFile);
|
auto *result = proToResult.value(source.proFileId);
|
||||||
if (!result)
|
if (!result)
|
||||||
result = fallback;
|
result = fallback;
|
||||||
result->foundFiles[type].insert(FileName::fromString(source.fileName));
|
result->foundFiles[type].insert(FileName::fromString(source.fileName));
|
||||||
@@ -304,12 +305,12 @@ void QmakePriFile::extractSources(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void QmakePriFile::extractInstalls(
|
void QmakePriFile::extractInstalls(
|
||||||
QHash<const ProFile *, QmakePriFileEvalResult *> proToResult, QmakePriFileEvalResult *fallback,
|
QHash<int, QmakePriFileEvalResult *> proToResult, QmakePriFileEvalResult *fallback,
|
||||||
const InstallsList &installList)
|
const InstallsList &installList)
|
||||||
{
|
{
|
||||||
for (const InstallsItem &item : installList.items) {
|
for (const InstallsItem &item : installList.items) {
|
||||||
for (const ProFileEvaluator::SourceFile &source : item.files) {
|
for (const ProFileEvaluator::SourceFile &source : item.files) {
|
||||||
auto *result = proToResult.value(source.proFile);
|
auto *result = proToResult.value(source.proFileId);
|
||||||
if (!result)
|
if (!result)
|
||||||
result = fallback;
|
result = fallback;
|
||||||
result->folders.insert(FileName::fromString(source.fileName));
|
result->folders.insert(FileName::fromString(source.fileName));
|
||||||
@@ -621,7 +622,8 @@ bool QmakePriFile::saveModifiedEditors()
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// force instant reload of ourselves
|
// force instant reload of ourselves
|
||||||
QtSupport::ProFileCacheManager::instance()->discardFile(filePath().toString());
|
QtSupport::ProFileCacheManager::instance()->discardFile(
|
||||||
|
filePath().toString(), m_project->qmakeVfs());
|
||||||
QmakeProject::notifyChanged(filePath());
|
QmakeProject::notifyChanged(filePath());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -701,7 +703,7 @@ QPair<ProFile *, QStringList> QmakePriFile::readProFile(const QString &file)
|
|||||||
QMakeVfs vfs;
|
QMakeVfs vfs;
|
||||||
QtSupport::ProMessageHandler handler;
|
QtSupport::ProMessageHandler handler;
|
||||||
QMakeParser parser(nullptr, &vfs, &handler);
|
QMakeParser parser(nullptr, &vfs, &handler);
|
||||||
includeFile = parser.parsedProBlock(QStringRef(&contents), file, 1);
|
includeFile = parser.parsedProBlock(QStringRef(&contents), 0, file, 1);
|
||||||
}
|
}
|
||||||
return qMakePair(includeFile, lines);
|
return qMakePair(includeFile, lines);
|
||||||
}
|
}
|
||||||
@@ -738,7 +740,7 @@ bool QmakePriFile::renameFile(const QString &oldName,
|
|||||||
QMakeParser parser(nullptr, nullptr, nullptr);
|
QMakeParser parser(nullptr, nullptr, nullptr);
|
||||||
QString contents = lines.join(QLatin1Char('\n'));
|
QString contents = lines.join(QLatin1Char('\n'));
|
||||||
includeFile = parser.parsedProBlock(QStringRef(&contents),
|
includeFile = parser.parsedProBlock(QStringRef(&contents),
|
||||||
filePath().toString(), 1, QMakeParser::FullGrammar);
|
0, filePath().toString(), 1, QMakeParser::FullGrammar);
|
||||||
QTC_ASSERT(includeFile, return false); // The file should still be valid after what we did.
|
QTC_ASSERT(includeFile, return false); // The file should still be valid after what we did.
|
||||||
|
|
||||||
ProWriter::addFiles(includeFile, &lines,
|
ProWriter::addFiles(includeFile, &lines,
|
||||||
@@ -1294,7 +1296,7 @@ QmakeEvalResult *QmakeProFile::evaluate(const QmakeEvalInput &input)
|
|||||||
result->includedFiles.proFile = pro;
|
result->includedFiles.proFile = pro;
|
||||||
result->includedFiles.name = input.projectFilePath;
|
result->includedFiles.name = input.projectFilePath;
|
||||||
|
|
||||||
QHash<const ProFile *, QmakePriFileEvalResult *> proToResult;
|
QHash<int, QmakePriFileEvalResult *> proToResult;
|
||||||
|
|
||||||
result->projectType
|
result->projectType
|
||||||
= proFileTemplateTypeToProjectType(
|
= proFileTemplateTypeToProjectType(
|
||||||
@@ -1332,7 +1334,7 @@ QmakeEvalResult *QmakeProFile::evaluate(const QmakeEvalInput &input)
|
|||||||
childTree->proFile = child;
|
childTree->proFile = child;
|
||||||
childTree->name = childName;
|
childTree->name = childName;
|
||||||
current->children.insert(childName, childTree);
|
current->children.insert(childName, childTree);
|
||||||
proToResult[child] = &childTree->result;
|
proToResult[child->id()] = &childTree->result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
toBuild.append(current->children.values());
|
toBuild.append(current->children.values());
|
||||||
@@ -1368,7 +1370,7 @@ QmakeEvalResult *QmakeProFile::evaluate(const QmakeEvalInput &input)
|
|||||||
childTree->proFile = child;
|
childTree->proFile = child;
|
||||||
childTree->name = childName;
|
childTree->name = childName;
|
||||||
current->children.insert(childName, childTree);
|
current->children.insert(childName, childTree);
|
||||||
proToResult[child] = &childTree->result;
|
proToResult[child->id()] = &childTree->result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
toBuild.append(current->children.values());
|
toBuild.append(current->children.values());
|
||||||
|
@@ -201,11 +201,11 @@ private:
|
|||||||
static QStringList baseVPaths(QtSupport::ProFileReader *reader, const QString &projectDir, const QString &buildDir);
|
static QStringList baseVPaths(QtSupport::ProFileReader *reader, const QString &projectDir, const QString &buildDir);
|
||||||
static QStringList fullVPaths(const QStringList &baseVPaths, QtSupport::ProFileReader *reader, const QString &qmakeVariable, const QString &projectDir);
|
static QStringList fullVPaths(const QStringList &baseVPaths, QtSupport::ProFileReader *reader, const QString &qmakeVariable, const QString &projectDir);
|
||||||
static void extractSources(
|
static void extractSources(
|
||||||
QHash<const ProFile *, Internal::QmakePriFileEvalResult *> proToResult,
|
QHash<int, Internal::QmakePriFileEvalResult *> proToResult,
|
||||||
Internal::QmakePriFileEvalResult *fallback,
|
Internal::QmakePriFileEvalResult *fallback,
|
||||||
QVector<ProFileEvaluator::SourceFile> sourceFiles, ProjectExplorer::FileType type);
|
QVector<ProFileEvaluator::SourceFile> sourceFiles, ProjectExplorer::FileType type);
|
||||||
static void extractInstalls(
|
static void extractInstalls(
|
||||||
QHash<const ProFile *, Internal::QmakePriFileEvalResult *> proToResult,
|
QHash<int, Internal::QmakePriFileEvalResult *> proToResult,
|
||||||
Internal::QmakePriFileEvalResult *fallback,
|
Internal::QmakePriFileEvalResult *fallback,
|
||||||
const InstallsList &installList);
|
const InstallsList &installList);
|
||||||
static void processValues(Internal::QmakePriFileEvalResult &result);
|
static void processValues(Internal::QmakePriFileEvalResult &result);
|
||||||
|
@@ -372,12 +372,14 @@ void QmakeProject::updateQmlJSCodeModel()
|
|||||||
QString errorMessage;
|
QString errorMessage;
|
||||||
foreach (const QString &rc, exactResources) {
|
foreach (const QString &rc, exactResources) {
|
||||||
QString contents;
|
QString contents;
|
||||||
if (m_qmakeVfs->readFile(rc, QMakeVfs::VfsExact, &contents, &errorMessage) == QMakeVfs::ReadOk)
|
int id = m_qmakeVfs->idForFileName(rc, QMakeVfs::VfsExact);
|
||||||
|
if (m_qmakeVfs->readFile(id, &contents, &errorMessage) == QMakeVfs::ReadOk)
|
||||||
projectInfo.resourceFileContents[rc] = contents;
|
projectInfo.resourceFileContents[rc] = contents;
|
||||||
}
|
}
|
||||||
foreach (const QString &rc, cumulativeResources) {
|
foreach (const QString &rc, cumulativeResources) {
|
||||||
QString contents;
|
QString contents;
|
||||||
if (m_qmakeVfs->readFile(rc, QMakeVfs::VfsCumulative, &contents, &errorMessage) == QMakeVfs::ReadOk)
|
int id = m_qmakeVfs->idForFileName(rc, QMakeVfs::VfsCumulative);
|
||||||
|
if (m_qmakeVfs->readFile(id, &contents, &errorMessage) == QMakeVfs::ReadOk)
|
||||||
projectInfo.resourceFileContents[rc] = contents;
|
projectInfo.resourceFileContents[rc] = contents;
|
||||||
}
|
}
|
||||||
if (!hasQmlLib) {
|
if (!hasQmlLib) {
|
||||||
@@ -734,7 +736,7 @@ void QmakeProject::destroyProFileReader(QtSupport::ProFileReader *reader)
|
|||||||
QString dir = projectFilePath().toString();
|
QString dir = projectFilePath().toString();
|
||||||
if (!dir.endsWith(QLatin1Char('/')))
|
if (!dir.endsWith(QLatin1Char('/')))
|
||||||
dir += QLatin1Char('/');
|
dir += QLatin1Char('/');
|
||||||
QtSupport::ProFileCacheManager::instance()->discardFiles(dir);
|
QtSupport::ProFileCacheManager::instance()->discardFiles(dir, qmakeVfs());
|
||||||
QtSupport::ProFileCacheManager::instance()->decRefCount();
|
QtSupport::ProFileCacheManager::instance()->decRefCount();
|
||||||
|
|
||||||
m_qmakeGlobals.reset();
|
m_qmakeGlobals.reset();
|
||||||
@@ -840,7 +842,8 @@ void QmakeProject::setAllBuildConfigurationsEnabled(bool enabled)
|
|||||||
static void notifyChangedHelper(const FileName &fileName, QmakeProFile *file)
|
static void notifyChangedHelper(const FileName &fileName, QmakeProFile *file)
|
||||||
{
|
{
|
||||||
if (file->filePath() == fileName) {
|
if (file->filePath() == fileName) {
|
||||||
QtSupport::ProFileCacheManager::instance()->discardFile(fileName.toString());
|
QtSupport::ProFileCacheManager::instance()->discardFile(
|
||||||
|
fileName.toString(), file->project()->qmakeVfs());
|
||||||
file->scheduleUpdate(QmakeProFile::ParseNow);
|
file->scheduleUpdate(QmakeProFile::ParseNow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -166,16 +166,17 @@ void ProFileCacheManager::clear()
|
|||||||
// loop is concerned. Use a shared pointer once this is not true anymore.
|
// loop is concerned. Use a shared pointer once this is not true anymore.
|
||||||
delete m_cache;
|
delete m_cache;
|
||||||
m_cache = 0;
|
m_cache = 0;
|
||||||
|
QMakeVfs::clearIds();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProFileCacheManager::discardFiles(const QString &prefix)
|
void ProFileCacheManager::discardFiles(const QString &prefix, QMakeVfs *vfs)
|
||||||
{
|
{
|
||||||
if (m_cache)
|
if (m_cache)
|
||||||
m_cache->discardFiles(prefix);
|
m_cache->discardFiles(prefix, vfs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProFileCacheManager::discardFile(const QString &fileName)
|
void ProFileCacheManager::discardFile(const QString &fileName, QMakeVfs *vfs)
|
||||||
{
|
{
|
||||||
if (m_cache)
|
if (m_cache)
|
||||||
m_cache->discardFile(fileName);
|
m_cache->discardFile(fileName, vfs);
|
||||||
}
|
}
|
||||||
|
@@ -93,8 +93,8 @@ class QTSUPPORT_EXPORT ProFileCacheManager : public QObject
|
|||||||
public:
|
public:
|
||||||
static ProFileCacheManager *instance() { return s_instance; }
|
static ProFileCacheManager *instance() { return s_instance; }
|
||||||
ProFileCache *cache();
|
ProFileCache *cache();
|
||||||
void discardFiles(const QString &prefix);
|
void discardFiles(const QString &prefix, QMakeVfs *vfs);
|
||||||
void discardFile(const QString &fileName);
|
void discardFile(const QString &fileName, QMakeVfs *vfs);
|
||||||
void incRefCount();
|
void incRefCount();
|
||||||
void decRefCount();
|
void decRefCount();
|
||||||
|
|
||||||
|
@@ -55,7 +55,7 @@ public:
|
|||||||
|
|
||||||
struct SourceFile {
|
struct SourceFile {
|
||||||
QString fileName;
|
QString fileName;
|
||||||
const ProFile *proFile;
|
int proFileId;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Call this from a concurrency-free context
|
// Call this from a concurrency-free context
|
||||||
|
@@ -474,9 +474,10 @@ bool ProStringList::contains(const char *str, Qt::CaseSensitivity cs) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProFile::ProFile(const QString &fileName)
|
ProFile::ProFile(int id, const QString &fileName)
|
||||||
: m_refCount(1),
|
: m_refCount(1),
|
||||||
m_fileName(fileName),
|
m_fileName(fileName),
|
||||||
|
m_id(id),
|
||||||
m_ok(true),
|
m_ok(true),
|
||||||
m_hostBuild(false)
|
m_hostBuild(false)
|
||||||
{
|
{
|
||||||
@@ -493,7 +494,7 @@ ProString ProFile::getStr(const ushort *&tPtr)
|
|||||||
{
|
{
|
||||||
uint len = *tPtr++;
|
uint len = *tPtr++;
|
||||||
ProString ret(items(), tPtr - tokPtr(), len);
|
ProString ret(items(), tPtr - tokPtr(), len);
|
||||||
ret.setSource(this);
|
ret.setSource(m_id);
|
||||||
tPtr += len;
|
tPtr += len;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@@ -69,8 +69,8 @@ public:
|
|||||||
void setValue(const QString &str);
|
void setValue(const QString &str);
|
||||||
void clear() { m_string.clear(); m_length = 0; }
|
void clear() { m_string.clear(); m_length = 0; }
|
||||||
ProString &setSource(const ProString &other) { m_file = other.m_file; return *this; }
|
ProString &setSource(const ProString &other) { m_file = other.m_file; return *this; }
|
||||||
ProString &setSource(const ProFile *pro) { m_file = pro; return *this; }
|
ProString &setSource(int id) { m_file = id; return *this; }
|
||||||
const ProFile *sourceFile() const { return m_file; }
|
int sourceFile() const { return m_file; }
|
||||||
|
|
||||||
ProString &prepend(const ProString &other);
|
ProString &prepend(const ProString &other);
|
||||||
ProString &append(const ProString &other, bool *pending = 0);
|
ProString &append(const ProString &other, bool *pending = 0);
|
||||||
@@ -159,7 +159,7 @@ private:
|
|||||||
|
|
||||||
QString m_string;
|
QString m_string;
|
||||||
int m_offset, m_length;
|
int m_offset, m_length;
|
||||||
const ProFile *m_file;
|
int m_file;
|
||||||
mutable uint m_hash;
|
mutable uint m_hash;
|
||||||
QChar *prepareExtend(int extraLen, int thisTarget, int extraTarget);
|
QChar *prepareExtend(int extraLen, int thisTarget, int extraTarget);
|
||||||
uint updatedHash() const;
|
uint updatedHash() const;
|
||||||
@@ -332,9 +332,10 @@ enum ProToken {
|
|||||||
class QMAKE_EXPORT ProFile
|
class QMAKE_EXPORT ProFile
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit ProFile(const QString &fileName);
|
ProFile(int id, const QString &fileName);
|
||||||
~ProFile();
|
~ProFile();
|
||||||
|
|
||||||
|
int id() const { return m_id; }
|
||||||
QString fileName() const { return m_fileName; }
|
QString fileName() const { return m_fileName; }
|
||||||
QString directoryName() const { return m_directoryName; }
|
QString directoryName() const { return m_directoryName; }
|
||||||
const QString &items() const { return m_proitems; }
|
const QString &items() const { return m_proitems; }
|
||||||
@@ -359,6 +360,7 @@ private:
|
|||||||
QString m_proitems;
|
QString m_proitems;
|
||||||
QString m_fileName;
|
QString m_fileName;
|
||||||
QString m_directoryName;
|
QString m_directoryName;
|
||||||
|
int m_id;
|
||||||
bool m_ok;
|
bool m_ok;
|
||||||
bool m_hostBuild;
|
bool m_hostBuild;
|
||||||
};
|
};
|
||||||
|
@@ -176,7 +176,7 @@ QString ProWriter::compileScope(const QString &scope)
|
|||||||
if (scope.isEmpty())
|
if (scope.isEmpty())
|
||||||
return QString();
|
return QString();
|
||||||
QMakeParser parser(0, 0, 0);
|
QMakeParser parser(0, 0, 0);
|
||||||
ProFile *includeFile = parser.parsedProBlock(QStringRef(&scope), QLatin1String("no-file"), 1);
|
ProFile *includeFile = parser.parsedProBlock(QStringRef(&scope), 0, QLatin1String("no-file"), 1);
|
||||||
if (!includeFile)
|
if (!includeFile)
|
||||||
return QString();
|
return QString();
|
||||||
QString result = includeFile->items();
|
QString result = includeFile->items();
|
||||||
|
@@ -436,13 +436,16 @@ QMakeEvaluator::VisitReturn
|
|||||||
QMakeEvaluator::writeFile(const QString &ctx, const QString &fn, QIODevice::OpenMode mode,
|
QMakeEvaluator::writeFile(const QString &ctx, const QString &fn, QIODevice::OpenMode mode,
|
||||||
QMakeVfs::VfsFlags flags, const QString &contents)
|
QMakeVfs::VfsFlags flags, const QString &contents)
|
||||||
{
|
{
|
||||||
|
int oldId = m_vfs->idForFileName(fn, flags | QMakeVfs::VfsAccessedOnly);
|
||||||
|
int id = m_vfs->idForFileName(fn, flags | QMakeVfs::VfsCreate);
|
||||||
QString errStr;
|
QString errStr;
|
||||||
if (!m_vfs->writeFile(fn, mode, flags, contents, &errStr)) {
|
if (!m_vfs->writeFile(id, 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;
|
||||||
}
|
}
|
||||||
m_parser->discardFileFromCache(fn);
|
if (oldId)
|
||||||
|
m_parser->discardFileFromCache(oldId);
|
||||||
return ReturnTrue;
|
return ReturnTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -709,9 +712,9 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand(
|
|||||||
after = args[3];
|
after = args[3];
|
||||||
const ProStringList &var = values(map(args.at(0)));
|
const ProStringList &var = values(map(args.at(0)));
|
||||||
if (!var.isEmpty()) {
|
if (!var.isEmpty()) {
|
||||||
const ProFile *src = currentProFile();
|
int src = currentFileId();
|
||||||
for (const ProString &v : var)
|
for (const ProString &v : var)
|
||||||
if (const ProFile *s = v.sourceFile()) {
|
if (int s = v.sourceFile()) {
|
||||||
src = s;
|
src = s;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1062,7 +1065,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand(
|
|||||||
dirs.append(fname + QLatin1Char('/'));
|
dirs.append(fname + QLatin1Char('/'));
|
||||||
}
|
}
|
||||||
if (regex.exactMatch(qdir[i]))
|
if (regex.exactMatch(qdir[i]))
|
||||||
ret += ProString(fname).setSource(currentProFile());
|
ret += ProString(fname).setSource(currentFileId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1329,7 +1332,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
|
|||||||
return ReturnFalse;
|
return ReturnFalse;
|
||||||
}
|
}
|
||||||
QString fn = resolvePath(args.at(0).toQString(m_tmp1));
|
QString fn = resolvePath(args.at(0).toQString(m_tmp1));
|
||||||
ProFile *pro = m_parser->parsedProFile(fn, QMakeParser::ParseOnlyCached);
|
QMakeVfs::VfsFlags flags = (m_cumulative ? QMakeVfs::VfsCumulative : QMakeVfs::VfsExact);
|
||||||
|
int pro = m_vfs->idForFileName(fn, flags | QMakeVfs::VfsAccessedOnly);
|
||||||
if (!pro)
|
if (!pro)
|
||||||
return ReturnFalse;
|
return ReturnFalse;
|
||||||
ProValueMap &vmap = m_valuemapStack.first();
|
ProValueMap &vmap = m_valuemapStack.first();
|
||||||
@@ -1349,18 +1353,17 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
|
|||||||
++vit;
|
++vit;
|
||||||
}
|
}
|
||||||
for (auto fit = m_functionDefs.testFunctions.begin(); fit != m_functionDefs.testFunctions.end(); ) {
|
for (auto fit = m_functionDefs.testFunctions.begin(); fit != m_functionDefs.testFunctions.end(); ) {
|
||||||
if (fit->pro() == pro)
|
if (fit->pro()->id() == pro)
|
||||||
fit = m_functionDefs.testFunctions.erase(fit);
|
fit = m_functionDefs.testFunctions.erase(fit);
|
||||||
else
|
else
|
||||||
++fit;
|
++fit;
|
||||||
}
|
}
|
||||||
for (auto fit = m_functionDefs.replaceFunctions.begin(); fit != m_functionDefs.replaceFunctions.end(); ) {
|
for (auto fit = m_functionDefs.replaceFunctions.begin(); fit != m_functionDefs.replaceFunctions.end(); ) {
|
||||||
if (fit->pro() == pro)
|
if (fit->pro()->id() == pro)
|
||||||
fit = m_functionDefs.replaceFunctions.erase(fit);
|
fit = m_functionDefs.replaceFunctions.erase(fit);
|
||||||
else
|
else
|
||||||
++fit;
|
++fit;
|
||||||
}
|
}
|
||||||
pro->deref();
|
|
||||||
ProStringList &iif = m_valuemapStack.first()[ProKey("QMAKE_INTERNAL_INCLUDED_FILES")];
|
ProStringList &iif = m_valuemapStack.first()[ProKey("QMAKE_INTERNAL_INCLUDED_FILES")];
|
||||||
int idx = iif.indexOf(ProString(fn));
|
int idx = iif.indexOf(ProString(fn));
|
||||||
if (idx >= 0)
|
if (idx >= 0)
|
||||||
@@ -1405,7 +1408,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
|
|||||||
VisitReturn ret = ReturnFalse;
|
VisitReturn ret = ReturnFalse;
|
||||||
QString contents = args.join(statics.field_sep);
|
QString contents = args.join(statics.field_sep);
|
||||||
ProFile *pro = m_parser->parsedProBlock(QStringRef(&contents),
|
ProFile *pro = m_parser->parsedProBlock(QStringRef(&contents),
|
||||||
m_current.pro->fileName(), m_current.line);
|
0, m_current.pro->fileName(), m_current.line);
|
||||||
if (m_cumulative || pro->isOk()) {
|
if (m_cumulative || pro->isOk()) {
|
||||||
m_locationStack.push(m_current);
|
m_locationStack.push(m_current);
|
||||||
visitProBlock(pro, pro->tokPtr());
|
visitProBlock(pro, pro->tokPtr());
|
||||||
|
@@ -268,13 +268,13 @@ void QMakeEvaluator::skipHashStr(const ushort *&tokPtr)
|
|||||||
|
|
||||||
// FIXME: this should not build new strings for direct sections.
|
// FIXME: this should not build new strings for direct sections.
|
||||||
// Note that the E_SPRINTF and E_LIST implementations rely on the deep copy.
|
// Note that the E_SPRINTF and E_LIST implementations rely on the deep copy.
|
||||||
ProStringList QMakeEvaluator::split_value_list(const QStringRef &vals, const ProFile *source)
|
ProStringList QMakeEvaluator::split_value_list(const QStringRef &vals, int source)
|
||||||
{
|
{
|
||||||
QString build;
|
QString build;
|
||||||
ProStringList ret;
|
ProStringList ret;
|
||||||
|
|
||||||
if (!source)
|
if (!source)
|
||||||
source = currentProFile();
|
source = currentFileId();
|
||||||
|
|
||||||
const QChar *vals_data = vals.data();
|
const QChar *vals_data = vals.data();
|
||||||
const int vals_len = vals.length();
|
const int vals_len = vals.length();
|
||||||
@@ -1311,7 +1311,7 @@ void QMakeEvaluator::setupProject()
|
|||||||
{
|
{
|
||||||
setTemplate();
|
setTemplate();
|
||||||
ProValueMap &vars = m_valuemapStack.top();
|
ProValueMap &vars = m_valuemapStack.top();
|
||||||
ProFile *proFile = currentProFile();
|
int proFile = currentFileId();
|
||||||
vars[ProKey("TARGET")] << ProString(QFileInfo(currentFileName()).baseName()).setSource(proFile);
|
vars[ProKey("TARGET")] << ProString(QFileInfo(currentFileName()).baseName()).setSource(proFile);
|
||||||
vars[ProKey("_PRO_FILE_")] << ProString(currentFileName()).setSource(proFile);
|
vars[ProKey("_PRO_FILE_")] << ProString(currentFileName()).setSource(proFile);
|
||||||
vars[ProKey("_PRO_FILE_PWD_")] << ProString(currentDirectory()).setSource(proFile);
|
vars[ProKey("_PRO_FILE_PWD_")] << ProString(currentDirectory()).setSource(proFile);
|
||||||
@@ -1321,7 +1321,7 @@ void QMakeEvaluator::setupProject()
|
|||||||
void QMakeEvaluator::evaluateCommand(const QString &cmds, const QString &where)
|
void QMakeEvaluator::evaluateCommand(const QString &cmds, const QString &where)
|
||||||
{
|
{
|
||||||
if (!cmds.isEmpty()) {
|
if (!cmds.isEmpty()) {
|
||||||
ProFile *pro = m_parser->parsedProBlock(QStringRef(&cmds), where, -1);
|
ProFile *pro = m_parser->parsedProBlock(QStringRef(&cmds), 0, where, -1);
|
||||||
if (pro->isOk()) {
|
if (pro->isOk()) {
|
||||||
m_locationStack.push(m_current);
|
m_locationStack.push(m_current);
|
||||||
visitProBlock(pro, pro->tokPtr());
|
visitProBlock(pro, pro->tokPtr());
|
||||||
@@ -1605,6 +1605,14 @@ ProFile *QMakeEvaluator::currentProFile() const
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int QMakeEvaluator::currentFileId() const
|
||||||
|
{
|
||||||
|
ProFile *pro = currentProFile();
|
||||||
|
if (pro)
|
||||||
|
return pro->id();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
QString QMakeEvaluator::currentFileName() const
|
QString QMakeEvaluator::currentFileName() const
|
||||||
{
|
{
|
||||||
ProFile *pro = currentProFile();
|
ProFile *pro = currentProFile();
|
||||||
@@ -1819,7 +1827,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConditional(
|
|||||||
const QStringRef &cond, const QString &where, int line)
|
const QStringRef &cond, const QString &where, int line)
|
||||||
{
|
{
|
||||||
VisitReturn ret = ReturnFalse;
|
VisitReturn ret = ReturnFalse;
|
||||||
ProFile *pro = m_parser->parsedProBlock(cond, where, line, QMakeParser::TestGrammar);
|
ProFile *pro = m_parser->parsedProBlock(cond, 0, where, line, QMakeParser::TestGrammar);
|
||||||
if (pro->isOk()) {
|
if (pro->isOk()) {
|
||||||
m_locationStack.push(m_current);
|
m_locationStack.push(m_current);
|
||||||
ret = visitProBlock(pro, pro->tokPtr());
|
ret = visitProBlock(pro, pro->tokPtr());
|
||||||
|
@@ -173,12 +173,13 @@ public:
|
|||||||
|
|
||||||
void setTemplate();
|
void setTemplate();
|
||||||
|
|
||||||
ProStringList split_value_list(const QStringRef &vals, const ProFile *source = 0);
|
ProStringList split_value_list(const QStringRef &vals, int source = 0);
|
||||||
VisitReturn expandVariableReferences(const ushort *&tokPtr, int sizeHint, ProStringList *ret, bool joined);
|
VisitReturn expandVariableReferences(const ushort *&tokPtr, int sizeHint, ProStringList *ret, bool joined);
|
||||||
|
|
||||||
QString currentFileName() const;
|
QString currentFileName() const;
|
||||||
QString currentDirectory() const;
|
QString currentDirectory() const;
|
||||||
ProFile *currentProFile() const;
|
ProFile *currentProFile() const;
|
||||||
|
int currentFileId() const;
|
||||||
QString resolvePath(const QString &fileName) const
|
QString resolvePath(const QString &fileName) const
|
||||||
{ return QMakeInternal::IoUtils::resolvePath(currentDirectory(), fileName); }
|
{ return QMakeInternal::IoUtils::resolvePath(currentDirectory(), fileName); }
|
||||||
|
|
||||||
|
@@ -49,12 +49,22 @@ ProFileCache::~ProFileCache()
|
|||||||
ent.pro->deref();
|
ent.pro->deref();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProFileCache::discardFile(const QString &fileName)
|
void ProFileCache::discardFile(const QString &fileName, QMakeVfs *vfs)
|
||||||
|
{
|
||||||
|
int eid = vfs->idForFileName(fileName, QMakeVfs::VfsExact | QMakeVfs::VfsAccessedOnly);
|
||||||
|
if (eid)
|
||||||
|
discardFile(eid);
|
||||||
|
int cid = vfs->idForFileName(fileName, QMakeVfs::VfsCumulative | QMakeVfs::VfsAccessedOnly);
|
||||||
|
if (cid && cid != eid)
|
||||||
|
discardFile(cid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProFileCache::discardFile(int id)
|
||||||
{
|
{
|
||||||
#ifdef PROPARSER_THREAD_SAFE
|
#ifdef PROPARSER_THREAD_SAFE
|
||||||
QMutexLocker lck(&mutex);
|
QMutexLocker lck(&mutex);
|
||||||
#endif
|
#endif
|
||||||
QHash<QString, Entry>::Iterator it = parsed_files.find(fileName);
|
auto it = parsed_files.find(id);
|
||||||
if (it != parsed_files.end()) {
|
if (it != parsed_files.end()) {
|
||||||
#ifdef PROPARSER_THREAD_SAFE
|
#ifdef PROPARSER_THREAD_SAFE
|
||||||
if (it->locker) {
|
if (it->locker) {
|
||||||
@@ -74,16 +84,16 @@ void ProFileCache::discardFile(const QString &fileName)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProFileCache::discardFiles(const QString &prefix)
|
void ProFileCache::discardFiles(const QString &prefix, QMakeVfs *vfs)
|
||||||
{
|
{
|
||||||
#ifdef PROPARSER_THREAD_SAFE
|
#ifdef PROPARSER_THREAD_SAFE
|
||||||
QMutexLocker lck(&mutex);
|
QMutexLocker lck(&mutex);
|
||||||
#endif
|
#endif
|
||||||
QHash<QString, Entry>::Iterator
|
auto it = parsed_files.begin(), end = parsed_files.end();
|
||||||
it = parsed_files.begin(),
|
while (it != end) {
|
||||||
end = parsed_files.end();
|
// Note: this is empty for virtual files from other VFSes.
|
||||||
while (it != end)
|
QString fn = vfs->fileNameForId(it.key());
|
||||||
if (it.key().startsWith(prefix)) {
|
if (fn.startsWith(prefix)) {
|
||||||
#ifdef PROPARSER_THREAD_SAFE
|
#ifdef PROPARSER_THREAD_SAFE
|
||||||
if (it->locker) {
|
if (it->locker) {
|
||||||
if (!it->locker->done) {
|
if (!it->locker->done) {
|
||||||
@@ -102,6 +112,7 @@ void ProFileCache::discardFiles(const QString &prefix)
|
|||||||
} else {
|
} else {
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////// Parser ///////////
|
////////// Parser ///////////
|
||||||
@@ -164,18 +175,15 @@ QMakeParser::QMakeParser(ProFileCache *cache, QMakeVfs *vfs, QMakeParserHandler
|
|||||||
ProFile *QMakeParser::parsedProFile(const QString &fileName, ParseFlags flags)
|
ProFile *QMakeParser::parsedProFile(const QString &fileName, ParseFlags flags)
|
||||||
{
|
{
|
||||||
ProFile *pro;
|
ProFile *pro;
|
||||||
if ((flags & (ParseUseCache|ParseOnlyCached)) && m_cache) {
|
QMakeVfs::VfsFlags vfsFlags = ((flags & ParseCumulative) ? QMakeVfs::VfsCumulative
|
||||||
|
: QMakeVfs::VfsExact);
|
||||||
|
int id = m_vfs->idForFileName(fileName, vfsFlags);
|
||||||
|
if ((flags & ParseUseCache) && m_cache) {
|
||||||
ProFileCache::Entry *ent;
|
ProFileCache::Entry *ent;
|
||||||
#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;
|
auto it = m_cache->parsed_files.find(id);
|
||||||
#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
|
||||||
@@ -192,24 +200,15 @@ ProFile *QMakeParser::parsedProFile(const QString &fileName, ParseFlags flags)
|
|||||||
#endif
|
#endif
|
||||||
if ((pro = ent->pro))
|
if ((pro = ent->pro))
|
||||||
pro->ref();
|
pro->ref();
|
||||||
} else if (!(flags & ParseOnlyCached)) {
|
} else {
|
||||||
QString contents;
|
ent = &m_cache->parsed_files[id];
|
||||||
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];
|
|
||||||
#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
|
||||||
if (virt || readFile(fileName, vfsFlags | QMakeVfs::VfsNoVirtual, flags, &contents)) {
|
QString contents;
|
||||||
pro = parsedProBlock(QStringRef(&contents), fileName, 1, FullGrammar);
|
if (readFile(id, flags, &contents)) {
|
||||||
|
pro = parsedProBlock(QStringRef(&contents), id, fileName, 1, FullGrammar);
|
||||||
pro->itemsRef()->squeeze();
|
pro->itemsRef()->squeeze();
|
||||||
pro->ref();
|
pro->ref();
|
||||||
} else {
|
} else {
|
||||||
@@ -226,46 +225,39 @@ ProFile *QMakeParser::parsedProFile(const QString &fileName, ParseFlags flags)
|
|||||||
ent->locker = 0;
|
ent->locker = 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} else {
|
|
||||||
pro = 0;
|
|
||||||
}
|
}
|
||||||
} else if (!(flags & ParseOnlyCached)) {
|
} else {
|
||||||
QString contents;
|
QString contents;
|
||||||
QMakeVfs::VfsFlags vfsFlags =
|
if (readFile(id, flags, &contents))
|
||||||
((flags & ParseCumulative) ? QMakeVfs::VfsCumulative : QMakeVfs::VfsExact);
|
pro = parsedProBlock(QStringRef(&contents), id, fileName, 1, FullGrammar);
|
||||||
if (readFile(fileName, vfsFlags, flags, &contents))
|
|
||||||
pro = parsedProBlock(QStringRef(&contents), fileName, 1, FullGrammar);
|
|
||||||
else
|
else
|
||||||
pro = 0;
|
pro = 0;
|
||||||
} else {
|
|
||||||
pro = 0;
|
|
||||||
}
|
}
|
||||||
return pro;
|
return pro;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProFile *QMakeParser::parsedProBlock(
|
ProFile *QMakeParser::parsedProBlock(
|
||||||
const QStringRef &contents, const QString &name, int line, SubGrammar grammar)
|
const QStringRef &contents, int id, const QString &name, int line, SubGrammar grammar)
|
||||||
{
|
{
|
||||||
ProFile *pro = new ProFile(name);
|
ProFile *pro = new ProFile(id, name);
|
||||||
read(pro, contents, line, grammar);
|
read(pro, contents, line, grammar);
|
||||||
return pro;
|
return pro;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QMakeParser::discardFileFromCache(const QString &fileName)
|
void QMakeParser::discardFileFromCache(int id)
|
||||||
{
|
{
|
||||||
if (m_cache)
|
if (m_cache)
|
||||||
m_cache->discardFile(fileName);
|
m_cache->discardFile(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QMakeParser::readFile(
|
bool QMakeParser::readFile(int id, ParseFlags flags, QString *contents)
|
||||||
const QString &fn, QMakeVfs::VfsFlags vfsFlags, ParseFlags flags, QString *contents)
|
|
||||||
{
|
{
|
||||||
QString errStr;
|
QString errStr;
|
||||||
QMakeVfs::ReadResult result = m_vfs->readFile(fn, vfsFlags, contents, &errStr);
|
QMakeVfs::ReadResult result = m_vfs->readFile(id, 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(fn, errStr));
|
fL1S("Cannot read %1: %2").arg(m_vfs->fileNameForId(id), errStr));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@@ -75,7 +75,6 @@ public:
|
|||||||
enum ParseFlag {
|
enum ParseFlag {
|
||||||
ParseDefault = 0,
|
ParseDefault = 0,
|
||||||
ParseUseCache = 1,
|
ParseUseCache = 1,
|
||||||
ParseOnlyCached = 2,
|
|
||||||
ParseReportMissing = 4,
|
ParseReportMissing = 4,
|
||||||
#ifdef PROEVALUATOR_DUAL_VFS
|
#ifdef PROEVALUATOR_DUAL_VFS
|
||||||
ParseCumulative = 8
|
ParseCumulative = 8
|
||||||
@@ -90,10 +89,10 @@ public:
|
|||||||
enum SubGrammar { FullGrammar, TestGrammar, ValueGrammar };
|
enum SubGrammar { FullGrammar, TestGrammar, ValueGrammar };
|
||||||
// fileName is expected to be absolute and cleanPath()ed.
|
// fileName is expected to be absolute and cleanPath()ed.
|
||||||
ProFile *parsedProFile(const QString &fileName, ParseFlags flags = ParseDefault);
|
ProFile *parsedProFile(const QString &fileName, ParseFlags flags = ParseDefault);
|
||||||
ProFile *parsedProBlock(const QStringRef &contents, const QString &name, int line = 0,
|
ProFile *parsedProBlock(const QStringRef &contents, int id, const QString &name, int line = 0,
|
||||||
SubGrammar grammar = FullGrammar);
|
SubGrammar grammar = FullGrammar);
|
||||||
|
|
||||||
void discardFileFromCache(const QString &fileName);
|
void discardFileFromCache(int id);
|
||||||
|
|
||||||
#ifdef PROPARSER_DEBUG
|
#ifdef PROPARSER_DEBUG
|
||||||
static QString formatProBlock(const QString &block);
|
static QString formatProBlock(const QString &block);
|
||||||
@@ -132,7 +131,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 readFile(const QString &fn, QMakeVfs::VfsFlags vfsFlags, QMakeParser::ParseFlags flags, QString *contents);
|
bool readFile(int id, 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);
|
||||||
@@ -201,8 +200,9 @@ public:
|
|||||||
ProFileCache() {}
|
ProFileCache() {}
|
||||||
~ProFileCache();
|
~ProFileCache();
|
||||||
|
|
||||||
void discardFile(const QString &fileName);
|
void discardFile(int id);
|
||||||
void discardFiles(const QString &prefix);
|
void discardFile(const QString &fileName, QMakeVfs *vfs);
|
||||||
|
void discardFiles(const QString &prefix, QMakeVfs *vfs);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Entry {
|
struct Entry {
|
||||||
@@ -218,7 +218,7 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
QHash<QString, Entry> parsed_files;
|
QHash<int, Entry> parsed_files;
|
||||||
#ifdef PROPARSER_THREAD_SAFE
|
#ifdef PROPARSER_THREAD_SAFE
|
||||||
QMutex mutex;
|
QMutex mutex;
|
||||||
#endif
|
#endif
|
||||||
|
@@ -51,19 +51,85 @@ QMakeVfs::QMakeVfs()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QMakeVfs::writeFile(const QString &fn, QIODevice::OpenMode mode, VfsFlags flags,
|
#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)
|
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[id];
|
||||||
QString *cont = &m_files[((flags & VfsCumulative) ? '-' : '+') + fn];
|
|
||||||
#else
|
|
||||||
QString *cont = &m_files[fn];
|
|
||||||
Q_UNUSED(flags)
|
Q_UNUSED(flags)
|
||||||
#endif
|
|
||||||
if (mode & QIODevice::Append)
|
if (mode & QIODevice::Append)
|
||||||
*cont += contents;
|
*cont += contents;
|
||||||
else
|
else
|
||||||
@@ -71,13 +137,13 @@ bool QMakeVfs::writeFile(const QString &fn, QIODevice::OpenMode mode, VfsFlags f
|
|||||||
Q_UNUSED(errStr)
|
Q_UNUSED(errStr)
|
||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
QFileInfo qfi(fn);
|
QFileInfo qfi(fileNameForId(id));
|
||||||
if (!QDir::current().mkpath(qfi.path())) {
|
if (!QDir::current().mkpath(qfi.path())) {
|
||||||
*errStr = fL1S("Cannot create parent directory");
|
*errStr = fL1S("Cannot create parent directory");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
QByteArray bytes = contents.toLocal8Bit();
|
QByteArray bytes = contents.toLocal8Bit();
|
||||||
QFile cfile(fn);
|
QFile cfile(qfi.filePath());
|
||||||
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 (flags & VfsExecutable) {
|
if (flags & VfsExecutable) {
|
||||||
@@ -108,53 +174,13 @@ bool QMakeVfs::writeFile(const QString &fn, QIODevice::OpenMode mode, VfsFlags f
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef PROEVALUATOR_FULL
|
QMakeVfs::ReadResult QMakeVfs::readFile(int id, QString *contents, QString *errStr)
|
||||||
bool QMakeVfs::readVirtualFile(const QString &fn, VfsFlags flags, QString *contents)
|
|
||||||
{
|
|
||||||
# ifdef PROEVALUATOR_THREAD_SAFE
|
|
||||||
QMutexLocker locker(&m_mutex);
|
|
||||||
# endif
|
|
||||||
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()
|
|
||||||
&& it->constData() != m_magicMissing.constData()
|
|
||||||
&& it->constData() != m_magicExisting.constData()) {
|
|
||||||
*contents = *it;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
Q_UNUSED(flags)
|
|
||||||
# endif
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
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;
|
auto it = m_files.constFind(id);
|
||||||
# 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");
|
||||||
@@ -165,15 +191,13 @@ QMakeVfs::ReadResult QMakeVfs::readFile(
|
|||||||
return ReadOk;
|
return ReadOk;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
Q_UNUSED(flags)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QFile file(fn);
|
QFile file(fileNameForId(id));
|
||||||
if (!file.open(QIODevice::ReadOnly)) {
|
if (!file.open(QIODevice::ReadOnly)) {
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
#ifndef PROEVALUATOR_FULL
|
#ifndef PROEVALUATOR_FULL
|
||||||
m_files[fn] = m_magicMissing;
|
m_files[id] = m_magicMissing;
|
||||||
#endif
|
#endif
|
||||||
*errStr = fL1S("No such file or directory");
|
*errStr = fL1S("No such file or directory");
|
||||||
return ReadNotFound;
|
return ReadNotFound;
|
||||||
@@ -182,7 +206,7 @@ QMakeVfs::ReadResult QMakeVfs::readFile(
|
|||||||
return ReadOtherError;
|
return ReadOtherError;
|
||||||
}
|
}
|
||||||
#ifndef PROEVALUATOR_FULL
|
#ifndef PROEVALUATOR_FULL
|
||||||
m_files[fn] = m_magicExisting;
|
m_files[id] = m_magicExisting;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QByteArray bcont = file.readAll();
|
QByteArray bcont = file.readAll();
|
||||||
@@ -205,15 +229,8 @@ bool QMakeVfs::exists(const QString &fn, VfsFlags flags)
|
|||||||
# ifdef PROEVALUATOR_THREAD_SAFE
|
# ifdef PROEVALUATOR_THREAD_SAFE
|
||||||
QMutexLocker locker(&m_mutex);
|
QMutexLocker locker(&m_mutex);
|
||||||
# endif
|
# endif
|
||||||
QHash<QString, QString>::ConstIterator it;
|
int id = idForFileName(fn, flags);
|
||||||
# ifdef PROEVALUATOR_DUAL_VFS
|
auto it = m_files.constFind(id);
|
||||||
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
|
#else
|
||||||
@@ -221,7 +238,7 @@ bool QMakeVfs::exists(const QString &fn, VfsFlags flags)
|
|||||||
#endif
|
#endif
|
||||||
bool ex = IoUtils::fileType(fn) == IoUtils::FileIsRegular;
|
bool ex = IoUtils::fileType(fn) == IoUtils::FileIsRegular;
|
||||||
#ifndef PROEVALUATOR_FULL
|
#ifndef PROEVALUATOR_FULL
|
||||||
m_files[fn] = ex ? m_magicExisting : m_magicMissing;
|
m_files[id] = ex ? m_magicExisting : m_magicMissing;
|
||||||
#endif
|
#endif
|
||||||
return ex;
|
return ex;
|
||||||
}
|
}
|
||||||
@@ -233,7 +250,7 @@ void QMakeVfs::invalidateCache()
|
|||||||
# ifdef PROEVALUATOR_THREAD_SAFE
|
# ifdef PROEVALUATOR_THREAD_SAFE
|
||||||
QMutexLocker locker(&m_mutex);
|
QMutexLocker locker(&m_mutex);
|
||||||
# endif
|
# 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) {
|
while (it != eit) {
|
||||||
if (it->constData() == m_magicMissing.constData()
|
if (it->constData() == m_magicMissing.constData()
|
||||||
||it->constData() == m_magicExisting.constData())
|
||it->constData() == m_magicExisting.constData())
|
||||||
|
@@ -27,13 +27,11 @@
|
|||||||
|
|
||||||
#include "qmake_global.h"
|
#include "qmake_global.h"
|
||||||
|
|
||||||
# include <qiodevice.h>
|
#include <qiodevice.h>
|
||||||
#ifndef PROEVALUATOR_FULL
|
#include <qhash.h>
|
||||||
# include <qhash.h>
|
#include <qstring.h>
|
||||||
# include <qstring.h>
|
#ifdef PROEVALUATOR_THREAD_SAFE
|
||||||
# ifdef PROEVALUATOR_THREAD_SAFE
|
# include <qmutex.h>
|
||||||
# include <qmutex.h>
|
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef QT_NO_TEXTCODEC
|
#ifndef QT_NO_TEXTCODEC
|
||||||
@@ -62,23 +60,27 @@ public:
|
|||||||
VfsExact = 0,
|
VfsExact = 0,
|
||||||
#ifdef PROEVALUATOR_DUAL_VFS
|
#ifdef PROEVALUATOR_DUAL_VFS
|
||||||
VfsCumulative = 2,
|
VfsCumulative = 2,
|
||||||
VfsNoVirtual = 4
|
VfsCreate = 4,
|
||||||
|
VfsCreatedOnly = 8,
|
||||||
#else
|
#else
|
||||||
VfsCumulative = 0,
|
VfsCumulative = 0,
|
||||||
VfsNoVirtual = 0
|
VfsCreate = 0,
|
||||||
|
VfsCreatedOnly = 0,
|
||||||
#endif
|
#endif
|
||||||
|
VfsAccessedOnly = 16
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS(VfsFlags, VfsFlag)
|
Q_DECLARE_FLAGS(VfsFlags, VfsFlag)
|
||||||
|
|
||||||
QMakeVfs();
|
QMakeVfs();
|
||||||
|
|
||||||
bool writeFile(const QString &fn, QIODevice::OpenMode mode, VfsFlags flags, const QString &contents, QString *errStr);
|
int idForFileName(const QString &fn, VfsFlags flags);
|
||||||
ReadResult readFile(const QString &fn, VfsFlags flags, QString *contents, QString *errStr);
|
QString fileNameForId(int id);
|
||||||
bool exists(const QString &fn, VfsFlags flags);
|
static void clearIds();
|
||||||
|
bool writeFile(int id, QIODevice::OpenMode mode, VfsFlags flags, const QString &contents, QString *errStr);
|
||||||
|
ReadResult readFile(int id, QString *contents, QString *errStr);
|
||||||
|
bool exists(const QString &fn, QMakeVfs::VfsFlags flags);
|
||||||
|
|
||||||
#ifndef PROEVALUATOR_FULL
|
#ifndef PROEVALUATOR_FULL
|
||||||
bool readVirtualFile(const QString &fn, VfsFlags flags, QString *contents);
|
|
||||||
|
|
||||||
void invalidateCache();
|
void invalidateCache();
|
||||||
void invalidateContents();
|
void invalidateContents();
|
||||||
#endif
|
#endif
|
||||||
@@ -88,11 +90,34 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
#ifdef PROEVALUATOR_THREAD_SAFE
|
||||||
|
static QMutex s_mutex;
|
||||||
|
#endif
|
||||||
|
static QAtomicInt s_fileIdCounter;
|
||||||
|
// Qt Creator's ProFile cache is a singleton to maximize its cross-project
|
||||||
|
// effectiveness (shared prf files from QtVersions).
|
||||||
|
// For this to actually work, real files need a global mapping.
|
||||||
|
// This is fine, because the namespace of real files is indeed global.
|
||||||
|
static QHash<QString, int> s_fileIdMap;
|
||||||
|
static QHash<int, QString> s_idFileMap;
|
||||||
|
#ifdef PROEVALUATOR_DUAL_VFS
|
||||||
|
# ifdef PROEVALUATOR_THREAD_SAFE
|
||||||
|
// The simple way to avoid recursing m_mutex.
|
||||||
|
QMutex m_vmutex;
|
||||||
|
# endif
|
||||||
|
// Virtual files are bound to the project context they were created in,
|
||||||
|
// so their ids need to be local as well.
|
||||||
|
// We violate that rule in lupdate (which has a non-dual VFS), but that
|
||||||
|
// does not matter, because it has only one project context anyway.
|
||||||
|
QHash<QString, int> m_virtualFileIdMap[2]; // Exact and cumulative
|
||||||
|
QHash<int, QString> m_virtualIdFileMap; // Only one map, as ids are unique across realms.
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef PROEVALUATOR_FULL
|
#ifndef PROEVALUATOR_FULL
|
||||||
# ifdef PROEVALUATOR_THREAD_SAFE
|
# ifdef PROEVALUATOR_THREAD_SAFE
|
||||||
QMutex m_mutex;
|
QMutex m_mutex;
|
||||||
# endif
|
# endif
|
||||||
QHash<QString, QString> m_files;
|
QHash<int, QString> m_files;
|
||||||
QString m_magicMissing;
|
QString m_magicMissing;
|
||||||
QString m_magicExisting;
|
QString m_magicExisting;
|
||||||
#endif
|
#endif
|
||||||
|
@@ -448,7 +448,7 @@ void tst_ProFileWriter::adds()
|
|||||||
|
|
||||||
QMakeVfs vfs;
|
QMakeVfs vfs;
|
||||||
QMakeParser parser(0, &vfs, &parseHandler);
|
QMakeParser parser(0, &vfs, &parseHandler);
|
||||||
ProFile *proFile = parser.parsedProBlock(QStringRef(&input), QLatin1String(BASE_DIR "/test.pro"), 1);
|
ProFile *proFile = parser.parsedProBlock(QStringRef(&input), 0, QLatin1String(BASE_DIR "/test.pro"), 1);
|
||||||
QVERIFY(proFile);
|
QVERIFY(proFile);
|
||||||
PW::putVarValues(proFile, &lines, values, var, PW::PutFlags(flags), scope);
|
PW::putVarValues(proFile, &lines, values, var, PW::PutFlags(flags), scope);
|
||||||
proFile->deref();
|
proFile->deref();
|
||||||
@@ -619,7 +619,7 @@ void tst_ProFileWriter::removes()
|
|||||||
|
|
||||||
QMakeVfs vfs;
|
QMakeVfs vfs;
|
||||||
QMakeParser parser(0, &vfs, &parseHandler);
|
QMakeParser parser(0, &vfs, &parseHandler);
|
||||||
ProFile *proFile = parser.parsedProBlock(QStringRef(&input), QLatin1String(BASE_DIR "/test.pro"), 1);
|
ProFile *proFile = parser.parsedProBlock(QStringRef(&input), 0, QLatin1String(BASE_DIR "/test.pro"), 1);
|
||||||
QVERIFY(proFile);
|
QVERIFY(proFile);
|
||||||
QmakeProjectManager::Internal::ProWriter::removeVarValues(proFile, &lines, values, vars);
|
QmakeProjectManager::Internal::ProWriter::removeVarValues(proFile, &lines, values, vars);
|
||||||
proFile->deref();
|
proFile->deref();
|
||||||
@@ -648,7 +648,7 @@ void tst_ProFileWriter::multiVar()
|
|||||||
|
|
||||||
QMakeVfs vfs;
|
QMakeVfs vfs;
|
||||||
QMakeParser parser(0, &vfs, &parseHandler);
|
QMakeParser parser(0, &vfs, &parseHandler);
|
||||||
ProFile *proFile = parser.parsedProBlock(QStringRef(&input), QLatin1String(BASE_DIR "/test.pro"), 1);
|
ProFile *proFile = parser.parsedProBlock(QStringRef(&input), 0, QLatin1String(BASE_DIR "/test.pro"), 1);
|
||||||
QVERIFY(proFile);
|
QVERIFY(proFile);
|
||||||
QmakeProjectManager::Internal::ProWriter::removeFiles(proFile, &lines, baseDir, files, vars);
|
QmakeProjectManager::Internal::ProWriter::removeFiles(proFile, &lines, baseDir, files, vars);
|
||||||
proFile->deref();
|
proFile->deref();
|
||||||
@@ -669,7 +669,7 @@ void tst_ProFileWriter::addFiles()
|
|||||||
|
|
||||||
QMakeVfs vfs;
|
QMakeVfs vfs;
|
||||||
QMakeParser parser(0, &vfs, &parseHandler);
|
QMakeParser parser(0, &vfs, &parseHandler);
|
||||||
ProFile *proFile = parser.parsedProBlock(QStringRef(&input), QLatin1String(BASE_DIR "/test.pro"), 1);
|
ProFile *proFile = parser.parsedProBlock(QStringRef(&input), 0, QLatin1String(BASE_DIR "/test.pro"), 1);
|
||||||
QVERIFY(proFile);
|
QVERIFY(proFile);
|
||||||
QmakeProjectManager::Internal::ProWriter::addFiles(proFile, &lines,
|
QmakeProjectManager::Internal::ProWriter::addFiles(proFile, &lines,
|
||||||
QStringList() << QString::fromLatin1(BASE_DIR "/sub/bar.cpp"),
|
QStringList() << QString::fromLatin1(BASE_DIR "/sub/bar.cpp"),
|
||||||
@@ -691,7 +691,7 @@ void tst_ProFileWriter::removeFiles()
|
|||||||
|
|
||||||
QMakeVfs vfs;
|
QMakeVfs vfs;
|
||||||
QMakeParser parser(0, &vfs, &parseHandler);
|
QMakeParser parser(0, &vfs, &parseHandler);
|
||||||
ProFile *proFile = parser.parsedProBlock(QStringRef(&input), QLatin1String(BASE_DIR "/test.pro"), 1);
|
ProFile *proFile = parser.parsedProBlock(QStringRef(&input), 0, QLatin1String(BASE_DIR "/test.pro"), 1);
|
||||||
QVERIFY(proFile);
|
QVERIFY(proFile);
|
||||||
QmakeProjectManager::Internal::ProWriter::removeFiles(proFile, &lines, QDir(BASE_DIR),
|
QmakeProjectManager::Internal::ProWriter::removeFiles(proFile, &lines, QDir(BASE_DIR),
|
||||||
QStringList() << QString::fromLatin1(BASE_DIR "/sub/bar.cpp"),
|
QStringList() << QString::fromLatin1(BASE_DIR "/sub/bar.cpp"),
|
||||||
|
Reference in New Issue
Block a user