Merge remote-tracking branch 'origin/5.11' into dev
Change-Id: I33b47095efdfe0ba698c6a88ca41ec911f432208
This commit is contained in:
commit
ffb2c2ac6c
@ -51,6 +51,7 @@
|
|||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QStandardItemModel>
|
#include <QStandardItemModel>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
#include <QTextStream>
|
||||||
|
|
||||||
#include "freezetablewidget.h"
|
#include "freezetablewidget.h"
|
||||||
|
|
||||||
@ -63,14 +64,16 @@ int main(int argc, char* argv[])
|
|||||||
|
|
||||||
QFile file(":/grades.txt");
|
QFile file(":/grades.txt");
|
||||||
if (file.open(QFile::ReadOnly)) {
|
if (file.open(QFile::ReadOnly)) {
|
||||||
QString line = file.readLine(200);
|
QTextStream stream(&file);
|
||||||
|
|
||||||
|
QString line = stream.readLine();
|
||||||
QStringList list = line.simplified().split(',');
|
QStringList list = line.simplified().split(',');
|
||||||
model->setHorizontalHeaderLabels(list);
|
model->setHorizontalHeaderLabels(list);
|
||||||
|
|
||||||
int row = 0;
|
int row = 0;
|
||||||
QStandardItem *newItem = 0;
|
QStandardItem *newItem = 0;
|
||||||
while (file.canReadLine()) {
|
while (!stream.atEnd()) {
|
||||||
line = file.readLine(200);
|
line = stream.readLine();
|
||||||
if (!line.startsWith('#') && line.contains(',')) {
|
if (!line.startsWith('#') && line.contains(',')) {
|
||||||
list = line.simplified().split(',');
|
list = line.simplified().split(',');
|
||||||
for (int col = 0; col < list.length(); ++col){
|
for (int col = 0; col < list.length(); ++col){
|
||||||
|
@ -38,5 +38,5 @@ defineTest(addExclusiveBuilds) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Default directories to process
|
# Default directories to process
|
||||||
QMAKE_DIR_REPLACE = OBJECTS_DIR MOC_DIR RCC_DIR PRECOMPILED_DIR QGLTF_DIR DESTDIR TRACEGEN_DIR
|
QMAKE_DIR_REPLACE = OBJECTS_DIR MOC_DIR RCC_DIR PRECOMPILED_DIR QGLTF_DIR DESTDIR TRACEGEN_DIR QMLCACHE_DIR
|
||||||
QMAKE_DIR_REPLACE_SANE += QGLTF_DIR TRACEGEN_DIR
|
QMAKE_DIR_REPLACE_SANE += QGLTF_DIR TRACEGEN_DIR QMLCACHE_DIR
|
||||||
|
@ -26,6 +26,7 @@ MOC_DIR = .moc
|
|||||||
RCC_DIR = .rcc
|
RCC_DIR = .rcc
|
||||||
UI_DIR = .uic
|
UI_DIR = .uic
|
||||||
TRACEGEN_DIR = .tracegen
|
TRACEGEN_DIR = .tracegen
|
||||||
|
QMLCACHE_DIR = .qmlcache
|
||||||
intel_icl {
|
intel_icl {
|
||||||
# ICL 14.0 has a bug that makes it not find #includes in dirs starting with .
|
# ICL 14.0 has a bug that makes it not find #includes in dirs starting with .
|
||||||
MOC_DIR = tmp/moc
|
MOC_DIR = tmp/moc
|
||||||
|
@ -60,7 +60,7 @@ IoUtils::FileType IoUtils::fileType(const QString &fileName)
|
|||||||
struct ::stat st;
|
struct ::stat st;
|
||||||
if (::stat(fileName.toLocal8Bit().constData(), &st))
|
if (::stat(fileName.toLocal8Bit().constData(), &st))
|
||||||
return FileNotFound;
|
return FileNotFound;
|
||||||
return S_ISDIR(st.st_mode) ? FileIsDir : FileIsRegular;
|
return S_ISDIR(st.st_mode) ? FileIsDir : S_ISREG(st.st_mode) ? FileIsRegular : FileNotFound;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,9 +258,8 @@ bool IoUtils::touchFile(const QString &targetFileName, const QString &referenceF
|
|||||||
# endif
|
# endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef Q_OS_UNIX
|
#if defined(QT_BUILD_QMAKE) && defined(Q_OS_UNIX)
|
||||||
bool IoUtils::readLinkTarget(const QString &symlinkPath, QString *target)
|
bool IoUtils::readLinkTarget(const QString &symlinkPath, QString *target)
|
||||||
{
|
{
|
||||||
const QByteArray localSymlinkPath = QFile::encodeName(symlinkPath);
|
const QByteArray localSymlinkPath = QFile::encodeName(symlinkPath);
|
||||||
@ -295,4 +294,6 @@ bool IoUtils::readLinkTarget(const QString &symlinkPath, QString *target)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif // PROEVALUATOR_FULL
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -29,6 +29,8 @@
|
|||||||
#ifndef IOUTILS_H
|
#ifndef IOUTILS_H
|
||||||
#define IOUTILS_H
|
#define IOUTILS_H
|
||||||
|
|
||||||
|
#include "qmake_global.h"
|
||||||
|
|
||||||
#include <qstring.h>
|
#include <qstring.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
@ -39,7 +41,7 @@ namespace QMakeInternal {
|
|||||||
This class provides replacement functionality for QFileInfo, QFile & QDir,
|
This class provides replacement functionality for QFileInfo, QFile & QDir,
|
||||||
as these are abysmally slow.
|
as these are abysmally slow.
|
||||||
*/
|
*/
|
||||||
class IoUtils {
|
class QMAKE_EXPORT IoUtils {
|
||||||
public:
|
public:
|
||||||
enum FileType {
|
enum FileType {
|
||||||
FileNotFound = 0,
|
FileNotFound = 0,
|
||||||
@ -64,10 +66,10 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
#if defined(PROEVALUATOR_FULL)
|
#if defined(PROEVALUATOR_FULL)
|
||||||
static bool touchFile(const QString &targetFileName, const QString &referenceFileName, QString *errorString);
|
static bool touchFile(const QString &targetFileName, const QString &referenceFileName, QString *errorString);
|
||||||
#endif
|
# if defined(QT_BUILD_QMAKE) && defined(Q_OS_UNIX)
|
||||||
#ifdef Q_OS_UNIX
|
|
||||||
static bool readLinkTarget(const QString &symlinkPath, QString *target);
|
static bool readLinkTarget(const QString &symlinkPath, QString *target);
|
||||||
# endif
|
# endif
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ProFileEvaluatorInternal
|
} // namespace ProFileEvaluatorInternal
|
||||||
|
@ -443,15 +443,18 @@ 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)
|
||||||
{
|
{
|
||||||
|
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, exe, 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1343,7 +1346,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));
|
||||||
int pro = m_parser->idForFileName(fn);
|
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();
|
||||||
@ -1416,7 +1420,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());
|
||||||
@ -1784,7 +1788,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());
|
||||||
@ -1796,7 +1800,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
|
|||||||
if (opt == QLatin1String("append")) {
|
if (opt == QLatin1String("append")) {
|
||||||
mode = QIODevice::Append;
|
mode = QIODevice::Append;
|
||||||
} else if (opt == QLatin1String("exe")) {
|
} else if (opt == QLatin1String("exe")) {
|
||||||
exe = true;
|
flags |= QMakeVfs::VfsExecutable;
|
||||||
} else {
|
} else {
|
||||||
evalError(fL1S("write_file(): invalid flag %1.").arg(opt.toQString(m_tmp3)));
|
evalError(fL1S("write_file(): invalid flag %1.").arg(opt.toQString(m_tmp3)));
|
||||||
return ReturnFalse;
|
return ReturnFalse;
|
||||||
@ -1806,7 +1810,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) {
|
||||||
@ -1960,6 +1964,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"));
|
||||||
@ -1983,12 +1988,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);
|
||||||
}
|
}
|
||||||
case T_RELOAD_PROPERTIES:
|
case T_RELOAD_PROPERTIES:
|
||||||
#ifdef QT_BUILD_QMAKE
|
#ifdef QT_BUILD_QMAKE
|
||||||
|
@ -1104,6 +1104,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;
|
||||||
@ -1114,7 +1115,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;
|
||||||
}
|
}
|
||||||
@ -1129,10 +1130,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)
|
||||||
@ -1160,7 +1161,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;
|
||||||
}
|
}
|
||||||
@ -1259,7 +1260,7 @@ bool QMakeEvaluator::loadSpec()
|
|||||||
goto cool;
|
goto cool;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
evalError(fL1S("Could not find qmake configuration file %1.").arg(qmakespec));
|
evalError(fL1S("Could not find qmake spec '%1'.").arg(qmakespec));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
cool:
|
cool:
|
||||||
@ -1285,7 +1286,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)
|
||||||
@ -1308,7 +1310,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());
|
||||||
@ -1812,7 +1814,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());
|
||||||
@ -1980,6 +1982,16 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateFeatureFile(
|
|||||||
// needs to be determined. Failed lookups are represented via non-null empty strings.
|
// needs to be determined. Failed lookups are represented via non-null empty strings.
|
||||||
QString *fnp = &m_featureRoots->cache[qMakePair(fn, currFn)];
|
QString *fnp = &m_featureRoots->cache[qMakePair(fn, currFn)];
|
||||||
if (fnp->isNull()) {
|
if (fnp->isNull()) {
|
||||||
|
#ifdef QMAKE_OVERRIDE_PRFS
|
||||||
|
{
|
||||||
|
QString ovrfn(QLatin1String(":/qmake/override_features/") + fn);
|
||||||
|
if (QFileInfo::exists(ovrfn)) {
|
||||||
|
fn = ovrfn;
|
||||||
|
goto cool;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
{
|
||||||
int start_root = 0;
|
int start_root = 0;
|
||||||
const QStringList &paths = m_featureRoots->paths;
|
const QStringList &paths = m_featureRoots->paths;
|
||||||
if (!currFn.isEmpty()) {
|
if (!currFn.isEmpty()) {
|
||||||
@ -1997,6 +2009,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateFeatureFile(
|
|||||||
goto cool;
|
goto cool;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#ifdef QMAKE_BUILTIN_PRFS
|
#ifdef QMAKE_BUILTIN_PRFS
|
||||||
fn.prepend(QLatin1String(":/qmake/features/"));
|
fn.prepend(QLatin1String(":/qmake/features/"));
|
||||||
if (QFileInfo::exists(fn))
|
if (QFileInfo::exists(fn))
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "qmakeparser.h"
|
#include "qmakeparser.h"
|
||||||
|
#include "qmakevfs.h"
|
||||||
#include "ioutils.h"
|
#include "ioutils.h"
|
||||||
|
|
||||||
#include <qlist.h>
|
#include <qlist.h>
|
||||||
@ -237,7 +238,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);
|
||||||
#if QT_CONFIG(process)
|
#if QT_CONFIG(process)
|
||||||
void runProcess(QProcess *proc, const QString &command) const;
|
void runProcess(QProcess *proc, const QString &command) const;
|
||||||
#endif
|
#endif
|
||||||
|
@ -327,6 +327,13 @@ bool QMakeGlobals::initProperties()
|
|||||||
QT_PCLOSE(proc);
|
QT_PCLOSE(proc);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
parseProperties(data, properties);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void QMakeGlobals::parseProperties(const QByteArray &data, QHash<ProKey, ProString> &properties)
|
||||||
|
{
|
||||||
const auto lines = data.split('\n');
|
const auto lines = data.split('\n');
|
||||||
for (QByteArray line : lines) {
|
for (QByteArray line : lines) {
|
||||||
int off = line.indexOf(':');
|
int off = line.indexOf(':');
|
||||||
@ -337,47 +344,50 @@ bool QMakeGlobals::initProperties()
|
|||||||
QString name = QString::fromLatin1(line.left(off));
|
QString name = QString::fromLatin1(line.left(off));
|
||||||
ProString value = ProString(QDir::fromNativeSeparators(
|
ProString value = ProString(QDir::fromNativeSeparators(
|
||||||
QString::fromLocal8Bit(line.mid(off + 1))));
|
QString::fromLocal8Bit(line.mid(off + 1))));
|
||||||
|
if (value.isNull())
|
||||||
|
value = ProString(""); // Make sure it is not null, to discern from missing keys
|
||||||
properties.insert(ProKey(name), value);
|
properties.insert(ProKey(name), value);
|
||||||
if (name.startsWith(QLatin1String("QT_"))) {
|
if (name.startsWith(QLatin1String("QT_"))) {
|
||||||
bool plain = !name.contains(QLatin1Char('/'));
|
enum { PropPut, PropRaw, PropGet } variant;
|
||||||
if (!plain) {
|
if (name.contains(QLatin1Char('/'))) {
|
||||||
if (!name.endsWith(QLatin1String("/get")))
|
if (name.endsWith(QLatin1String("/raw")))
|
||||||
|
variant = PropRaw;
|
||||||
|
else if (name.endsWith(QLatin1String("/get")))
|
||||||
|
variant = PropGet;
|
||||||
|
else // Nothing falls back on /src or /dev.
|
||||||
continue;
|
continue;
|
||||||
name.chop(4);
|
name.chop(4);
|
||||||
|
} else {
|
||||||
|
variant = PropPut;
|
||||||
}
|
}
|
||||||
if (name.startsWith(QLatin1String("QT_INSTALL_"))) {
|
if (name.startsWith(QLatin1String("QT_INSTALL_"))) {
|
||||||
if (plain) {
|
if (variant < PropRaw) {
|
||||||
properties.insert(ProKey(name + QLatin1String("/raw")), value);
|
|
||||||
properties.insert(ProKey(name + QLatin1String("/get")), value);
|
|
||||||
}
|
|
||||||
properties.insert(ProKey(name + QLatin1String("/src")), value);
|
|
||||||
if (name == QLatin1String("QT_INSTALL_PREFIX")
|
if (name == QLatin1String("QT_INSTALL_PREFIX")
|
||||||
|| name == QLatin1String("QT_INSTALL_DATA")
|
|| name == QLatin1String("QT_INSTALL_DATA")
|
||||||
|
|| name == QLatin1String("QT_INSTALL_LIBS")
|
||||||
|| name == QLatin1String("QT_INSTALL_BINS")) {
|
|| name == QLatin1String("QT_INSTALL_BINS")) {
|
||||||
name.replace(3, 7, QLatin1String("HOST"));
|
// Qt4 fallback
|
||||||
if (plain) {
|
QString hname = name;
|
||||||
properties.insert(ProKey(name), value);
|
hname.replace(3, 7, QLatin1String("HOST"));
|
||||||
properties.insert(ProKey(name + QLatin1String("/get")), value);
|
properties.insert(ProKey(hname), value);
|
||||||
|
properties.insert(ProKey(hname + QLatin1String("/get")), value);
|
||||||
|
properties.insert(ProKey(hname + QLatin1String("/src")), value);
|
||||||
}
|
}
|
||||||
properties.insert(ProKey(name + QLatin1String("/src")), value);
|
properties.insert(ProKey(name + QLatin1String("/raw")), value);
|
||||||
}
|
}
|
||||||
} else if (name.startsWith(QLatin1String("QT_HOST_"))) {
|
if (variant <= PropRaw)
|
||||||
if (plain)
|
properties.insert(ProKey(name + QLatin1String("/dev")), value);
|
||||||
|
} else if (!name.startsWith(QLatin1String("QT_HOST_"))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (variant != PropRaw) {
|
||||||
|
if (variant < PropGet)
|
||||||
properties.insert(ProKey(name + QLatin1String("/get")), value);
|
properties.insert(ProKey(name + QLatin1String("/get")), value);
|
||||||
properties.insert(ProKey(name + QLatin1String("/src")), value);
|
properties.insert(ProKey(name + QLatin1String("/src")), value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
void QMakeGlobals::setProperties(const QHash<QString, QString> &props)
|
|
||||||
{
|
|
||||||
QHash<QString, QString>::ConstIterator it = props.constBegin(), eit = props.constEnd();
|
|
||||||
for (; it != eit; ++it)
|
|
||||||
properties.insert(ProKey(it.key()), ProString(it.value()));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif // QT_BUILD_QMAKE
|
#endif // QT_BUILD_QMAKE
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -131,10 +131,10 @@ public:
|
|||||||
void reloadProperties() { property->reload(); }
|
void reloadProperties() { property->reload(); }
|
||||||
ProString propertyValue(const ProKey &name) const { return property->value(name); }
|
ProString propertyValue(const ProKey &name) const { return property->value(name); }
|
||||||
#else
|
#else
|
||||||
|
static void parseProperties(const QByteArray &data, QHash<ProKey, ProString> &props);
|
||||||
# ifdef PROEVALUATOR_INIT_PROPS
|
# ifdef PROEVALUATOR_INIT_PROPS
|
||||||
bool initProperties();
|
bool initProperties();
|
||||||
# else
|
# else
|
||||||
void setProperties(const QHash<QString, QString> &props);
|
|
||||||
void setProperties(const QHash<ProKey, ProString> &props) { properties = props; }
|
void setProperties(const QHash<ProKey, ProString> &props) { properties = props; }
|
||||||
# endif
|
# endif
|
||||||
ProString propertyValue(const ProKey &name) const { return properties.value(name); }
|
ProString propertyValue(const ProKey &name) const { return properties.value(name); }
|
||||||
|
@ -52,12 +52,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) {
|
||||||
@ -77,16 +87,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) {
|
||||||
@ -106,6 +116,7 @@ void ProFileCache::discardFiles(const QString &prefix)
|
|||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////// Parser ///////////
|
////////// Parser ///////////
|
||||||
|
|
||||||
@ -167,12 +178,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;
|
||||||
|
QMakeVfs::VfsFlags vfsFlags = ((flags & ParseCumulative) ? QMakeVfs::VfsCumulative
|
||||||
|
: QMakeVfs::VfsExact);
|
||||||
|
int id = m_vfs->idForFileName(fileName, vfsFlags);
|
||||||
if ((flags & ParseUseCache) && m_cache) {
|
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 = m_cache->parsed_files.find(fileName);
|
auto it = m_cache->parsed_files.find(id);
|
||||||
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
|
||||||
@ -190,18 +204,18 @@ ProFile *QMakeParser::parsedProFile(const QString &fileName, ParseFlags flags)
|
|||||||
if ((pro = ent->pro))
|
if ((pro = ent->pro))
|
||||||
pro->ref();
|
pro->ref();
|
||||||
} else {
|
} else {
|
||||||
ent = &m_cache->parsed_files[fileName];
|
ent = &m_cache->parsed_files[id];
|
||||||
#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(idForFileName(fileName), fileName);
|
QString contents;
|
||||||
if (!read(pro, flags)) {
|
if (readFile(id, flags, &contents)) {
|
||||||
delete pro;
|
pro = parsedProBlock(QStringRef(&contents), id, fileName, 1, FullGrammar);
|
||||||
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
|
||||||
@ -216,51 +230,39 @@ ProFile *QMakeParser::parsedProFile(const QString &fileName, ParseFlags flags)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pro = new ProFile(idForFileName(fileName), fileName);
|
QString contents;
|
||||||
if (!read(pro, flags)) {
|
if (readFile(id, flags, &contents))
|
||||||
delete pro;
|
pro = parsedProBlock(QStringRef(&contents), id, fileName, 1, FullGrammar);
|
||||||
|
else
|
||||||
pro = 0;
|
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(0, name);
|
ProFile *pro = new ProFile(id, name);
|
||||||
read(pro, contents, line, grammar);
|
read(pro, contents, line, grammar);
|
||||||
return pro;
|
return pro;
|
||||||
}
|
}
|
||||||
|
|
||||||
int QMakeParser::idForFileName(const QString &fileName)
|
void QMakeParser::discardFileFromCache(int id)
|
||||||
{
|
|
||||||
#ifdef PROPARSER_THREAD_SAFE
|
|
||||||
QMutexLocker lck(&fileIdMutex);
|
|
||||||
#endif
|
|
||||||
int &place = fileIdMap[fileName];
|
|
||||||
if (!place)
|
|
||||||
place = ++fileIdCounter;
|
|
||||||
return place;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QMakeParser::discardFileFromCache(const QString &fileName)
|
|
||||||
{
|
{
|
||||||
if (m_cache)
|
if (m_cache)
|
||||||
m_cache->discardFile(fileName);
|
m_cache->discardFile(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QMakeParser::read(ProFile *pro, ParseFlags flags)
|
bool QMakeParser::readFile(int id, ParseFlags flags, QString *contents)
|
||||||
{
|
{
|
||||||
QString content;
|
|
||||||
QString errStr;
|
QString errStr;
|
||||||
if (!m_vfs->readFile(pro->fileName(), &content, &errStr)) {
|
QMakeVfs::ReadResult result = m_vfs->readFile(id, contents, &errStr);
|
||||||
if (m_handler && ((flags & ParseReportMissing) || m_vfs->exists(pro->fileName())))
|
if (result != QMakeVfs::ReadOk) {
|
||||||
|
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(m_vfs->fileNameForId(id), errStr));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
read(pro, QStringRef(&content), 1, FullGrammar);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#define QMAKEPARSER_H
|
#define QMAKEPARSER_H
|
||||||
|
|
||||||
#include "qmake_global.h"
|
#include "qmake_global.h"
|
||||||
|
#include "qmakevfs.h"
|
||||||
#include "proitems.h"
|
#include "proitems.h"
|
||||||
|
|
||||||
#include <qhash.h>
|
#include <qhash.h>
|
||||||
@ -78,7 +79,12 @@ public:
|
|||||||
enum ParseFlag {
|
enum ParseFlag {
|
||||||
ParseDefault = 0,
|
ParseDefault = 0,
|
||||||
ParseUseCache = 1,
|
ParseUseCache = 1,
|
||||||
ParseReportMissing = 4
|
ParseReportMissing = 4,
|
||||||
|
#ifdef PROEVALUATOR_DUAL_VFS
|
||||||
|
ParseCumulative = 8
|
||||||
|
#else
|
||||||
|
ParseCumulative = 0
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS(ParseFlags, ParseFlag)
|
Q_DECLARE_FLAGS(ParseFlags, ParseFlag)
|
||||||
|
|
||||||
@ -87,12 +93,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);
|
||||||
|
|
||||||
int idForFileName(const QString &fileName);
|
void discardFileFromCache(int id);
|
||||||
|
|
||||||
void discardFileFromCache(const QString &fileName);
|
|
||||||
|
|
||||||
#ifdef PROPARSER_DEBUG
|
#ifdef PROPARSER_DEBUG
|
||||||
static QString formatProBlock(const QString &block);
|
static QString formatProBlock(const QString &block);
|
||||||
@ -131,7 +135,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(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);
|
||||||
@ -182,12 +186,6 @@ private:
|
|||||||
|
|
||||||
QString m_tmp; // Temporary for efficient toQString
|
QString m_tmp; // Temporary for efficient toQString
|
||||||
|
|
||||||
QHash<QString, int> fileIdMap;
|
|
||||||
#ifdef PROEVALUATOR_THREAD_SAFE
|
|
||||||
QMutex fileIdMutex;
|
|
||||||
#endif
|
|
||||||
int fileIdCounter = 0;
|
|
||||||
|
|
||||||
ProFileCache *m_cache;
|
ProFileCache *m_cache;
|
||||||
QMakeParserHandler *m_handler;
|
QMakeParserHandler *m_handler;
|
||||||
QMakeVfs *m_vfs;
|
QMakeVfs *m_vfs;
|
||||||
@ -206,8 +204,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 {
|
||||||
@ -223,7 +222,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
|
||||||
|
@ -35,6 +35,10 @@ using namespace QMakeInternal;
|
|||||||
#include <qfile.h>
|
#include <qfile.h>
|
||||||
#include <qfileinfo.h>
|
#include <qfileinfo.h>
|
||||||
|
|
||||||
|
#ifndef QT_NO_TEXTCODEC
|
||||||
|
#include <qtextcodec.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define fL1S(s) QString::fromLatin1(s)
|
#define fL1S(s) QString::fromLatin1(s)
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
@ -45,34 +49,107 @@ QMakeVfs::QMakeVfs()
|
|||||||
, m_magicExisting(fL1S("existing"))
|
, m_magicExisting(fL1S("existing"))
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
#ifndef QT_NO_TEXTCODEC
|
||||||
|
m_textCodec = 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
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
|
||||||
QString *cont = &m_files[fn];
|
QString *cont = &m_files[id];
|
||||||
|
Q_UNUSED(flags)
|
||||||
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(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 (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 {
|
||||||
@ -93,70 +170,78 @@ 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;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QMakeVfs::readFile(const QString &fn, QString *contents, QString *errStr)
|
QMakeVfs::ReadResult QMakeVfs::readFile(int id, 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);
|
auto it = m_files.constFind(id);
|
||||||
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");
|
||||||
return false;
|
return ReadNotFound;
|
||||||
}
|
}
|
||||||
if (it->constData() != m_magicExisting.constData()) {
|
if (it->constData() != m_magicExisting.constData()) {
|
||||||
*contents = *it;
|
*contents = *it;
|
||||||
return true;
|
return ReadOk;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QFile file(fn);
|
QFile file(fileNameForId(id));
|
||||||
if (!file.open(QIODevice::ReadOnly)) {
|
if (!file.open(QIODevice::ReadOnly)) {
|
||||||
|
if (!file.exists()) {
|
||||||
#ifndef PROEVALUATOR_FULL
|
#ifndef PROEVALUATOR_FULL
|
||||||
if (!IoUtils::exists(fn)) {
|
m_files[id] = m_magicMissing;
|
||||||
m_files[fn] = m_magicMissing;
|
|
||||||
*errStr = fL1S("No such file or directory");
|
|
||||||
} else
|
|
||||||
#endif
|
#endif
|
||||||
|
*errStr = fL1S("No such file or directory");
|
||||||
|
return ReadNotFound;
|
||||||
|
}
|
||||||
*errStr = file.errorString();
|
*errStr = file.errorString();
|
||||||
return false;
|
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();
|
||||||
if (bcont.startsWith("\xef\xbb\xbf")) {
|
if (bcont.startsWith("\xef\xbb\xbf")) {
|
||||||
// UTF-8 BOM will cause subtle errors
|
// UTF-8 BOM will cause subtle errors
|
||||||
*errStr = fL1S("Unexpected UTF-8 BOM");
|
*errStr = fL1S("Unexpected UTF-8 BOM");
|
||||||
return false;
|
return ReadOtherError;
|
||||||
}
|
}
|
||||||
*contents = QString::fromLocal8Bit(bcont);
|
*contents =
|
||||||
return true;
|
#ifndef QT_NO_TEXTCODEC
|
||||||
|
m_textCodec ? m_textCodec->toUnicode(bcont) :
|
||||||
|
#endif
|
||||||
|
QString::fromLocal8Bit(bcont);
|
||||||
|
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);
|
int id = idForFileName(fn, flags);
|
||||||
|
auto it = m_files.constFind(id);
|
||||||
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::exists(fn);
|
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;
|
||||||
}
|
}
|
||||||
@ -168,7 +253,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())
|
||||||
@ -188,4 +273,11 @@ void QMakeVfs::invalidateContents()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef QT_NO_TEXTCODEC
|
||||||
|
void QMakeVfs::setTextCodec(const QTextCodec *textCodec)
|
||||||
|
{
|
||||||
|
m_textCodec = textCodec;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -32,12 +32,20 @@
|
|||||||
#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
|
||||||
|
|
||||||
|
#ifndef QT_NO_TEXTCODEC
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QTextCodec)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PROEVALUATOR_DUAL_VFS
|
||||||
|
# ifndef PROEVALUATOR_CUMULATIVE
|
||||||
|
# error PROEVALUATOR_DUAL_VFS requires PROEVALUATOR_CUMULATIVE
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
@ -45,28 +53,85 @@ QT_BEGIN_NAMESPACE
|
|||||||
class QMAKE_EXPORT QMakeVfs
|
class QMAKE_EXPORT QMakeVfs
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum ReadResult {
|
||||||
|
ReadOk,
|
||||||
|
ReadNotFound,
|
||||||
|
ReadOtherError
|
||||||
|
};
|
||||||
|
|
||||||
|
enum VfsFlag {
|
||||||
|
VfsExecutable = 1,
|
||||||
|
VfsExact = 0,
|
||||||
|
#ifdef PROEVALUATOR_DUAL_VFS
|
||||||
|
VfsCumulative = 2,
|
||||||
|
VfsCreate = 4,
|
||||||
|
VfsCreatedOnly = 8,
|
||||||
|
#else
|
||||||
|
VfsCumulative = 0,
|
||||||
|
VfsCreate = 0,
|
||||||
|
VfsCreatedOnly = 0,
|
||||||
|
#endif
|
||||||
|
VfsAccessedOnly = 16
|
||||||
|
};
|
||||||
|
Q_DECLARE_FLAGS(VfsFlags, VfsFlag)
|
||||||
|
|
||||||
QMakeVfs();
|
QMakeVfs();
|
||||||
|
|
||||||
bool writeFile(const QString &fn, QIODevice::OpenMode mode, bool exe, const QString &contents, QString *errStr);
|
int idForFileName(const QString &fn, VfsFlags flags);
|
||||||
bool readFile(const QString &fn, QString *contents, QString *errStr);
|
QString fileNameForId(int id);
|
||||||
bool exists(const QString &fn);
|
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
|
||||||
void invalidateCache();
|
void invalidateCache();
|
||||||
void invalidateContents();
|
void invalidateContents();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef QT_NO_TEXTCODEC
|
||||||
|
void setTextCodec(const QTextCodec *textCodec);
|
||||||
|
#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
|
||||||
|
#ifndef QT_NO_TEXTCODEC
|
||||||
|
const QTextCodec *m_textCodec;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_OPERATORS_FOR_FLAGS(QMakeVfs::VfsFlags)
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // QMAKEVFS_H
|
#endif // QMAKEVFS_H
|
||||||
|
@ -123,7 +123,7 @@ QStringList QMakeProject::expand(const ProKey &func, const QList<ProStringList>
|
|||||||
ProString QMakeProject::expand(const QString &expr, const QString &where, int line)
|
ProString QMakeProject::expand(const QString &expr, const QString &where, int line)
|
||||||
{
|
{
|
||||||
ProString ret;
|
ProString ret;
|
||||||
ProFile *pro = m_parser->parsedProBlock(QStringRef(&expr), where, line,
|
ProFile *pro = m_parser->parsedProBlock(QStringRef(&expr), 0, where, line,
|
||||||
QMakeParser::ValueGrammar);
|
QMakeParser::ValueGrammar);
|
||||||
if (pro->isOk()) {
|
if (pro->isOk()) {
|
||||||
m_current.pro = pro;
|
m_current.pro = pro;
|
||||||
|
@ -395,10 +395,10 @@ QByteArray ba = QByteArray::number(12.3456, 'E', 3);
|
|||||||
|
|
||||||
//! [43]
|
//! [43]
|
||||||
static const char mydata[] = {
|
static const char mydata[] = {
|
||||||
0x00, 0x00, 0x03, 0x84, 0x78, 0x9c, 0x3b, 0x76,
|
'\x00', '\x00', '\x03', '\x84', '\x78', '\x9c', '\x3b', '\x76',
|
||||||
0xec, 0x18, 0xc3, 0x31, 0x0a, 0xf1, 0xcc, 0x99,
|
'\xec', '\x18', '\xc3', '\x31', '\x0a', '\xf1', '\xcc', '\x99',
|
||||||
...
|
...
|
||||||
0x6d, 0x5b
|
'\x6d', '\x5b'
|
||||||
};
|
};
|
||||||
|
|
||||||
QByteArray data = QByteArray::fromRawData(mydata, sizeof(mydata));
|
QByteArray data = QByteArray::fromRawData(mydata, sizeof(mydata));
|
||||||
|
@ -120,12 +120,12 @@ using namespace QtFutex;
|
|||||||
|
|
||||||
If the system has the ability to wake up a precise number of threads, has
|
If the system has the ability to wake up a precise number of threads, has
|
||||||
Linux's FUTEX_WAKE_OP functionality, and is 64-bit, instead of using a
|
Linux's FUTEX_WAKE_OP functionality, and is 64-bit, instead of using a
|
||||||
single bit indicating a contended semaphore, we'll store the total number
|
single bit indicating a contended semaphore, we'll store the number of
|
||||||
of waiters in the high word. Additionally, all multi-token waiters will be
|
tokens *plus* total number of waiters in the high word. Additionally, all
|
||||||
waiting on that high word. So when releasing n tokens on those systems, we
|
multi-token waiters will be waiting on that high word. So when releasing n
|
||||||
tell the kernel to wake up n single-token threads and all of the
|
tokens on those systems, we tell the kernel to wake up n single-token
|
||||||
multi-token ones. Which threads get woken up is unspecified, but it's
|
threads and all of the multi-token ones. Which threads get woken up is
|
||||||
likely single-token threads will get woken up first.
|
unspecified, but it's likely single-token threads will get woken up first.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(FUTEX_OP) && QT_POINTER_SIZE > 4
|
#if defined(FUTEX_OP) && QT_POINTER_SIZE > 4
|
||||||
@ -231,10 +231,14 @@ template <bool IsTimed> bool futexSemaphoreTryAcquire(QBasicAtomicInteger<quintp
|
|||||||
{
|
{
|
||||||
// Try to acquire without waiting (we still loop because the testAndSet
|
// Try to acquire without waiting (we still loop because the testAndSet
|
||||||
// call can fail).
|
// call can fail).
|
||||||
|
quintptr nn = unsigned(n);
|
||||||
|
if (futexHasWaiterCount)
|
||||||
|
nn |= quint64(nn) << 32; // token count replicated in high word
|
||||||
|
|
||||||
quintptr curValue = u.loadAcquire();
|
quintptr curValue = u.loadAcquire();
|
||||||
while (futexAvailCounter(curValue) >= n) {
|
while (futexAvailCounter(curValue) >= n) {
|
||||||
// try to acquire
|
// try to acquire
|
||||||
quintptr newValue = curValue - n;
|
quintptr newValue = curValue - nn;
|
||||||
if (u.testAndSetOrdered(curValue, newValue, curValue))
|
if (u.testAndSetOrdered(curValue, newValue, curValue))
|
||||||
return true; // succeeded!
|
return true; // succeeded!
|
||||||
}
|
}
|
||||||
@ -242,7 +246,6 @@ template <bool IsTimed> bool futexSemaphoreTryAcquire(QBasicAtomicInteger<quintp
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// we need to wait
|
// we need to wait
|
||||||
quintptr valueToSubtract = unsigned(n);
|
|
||||||
quintptr oneWaiter = quintptr(Q_UINT64_C(1) << 32); // zero on 32-bit
|
quintptr oneWaiter = quintptr(Q_UINT64_C(1) << 32); // zero on 32-bit
|
||||||
if (futexHasWaiterCount) {
|
if (futexHasWaiterCount) {
|
||||||
// increase the waiter count
|
// increase the waiter count
|
||||||
@ -250,14 +253,15 @@ template <bool IsTimed> bool futexSemaphoreTryAcquire(QBasicAtomicInteger<quintp
|
|||||||
|
|
||||||
// We don't use the fetched value from above so futexWait() fails if
|
// We don't use the fetched value from above so futexWait() fails if
|
||||||
// it changed after the testAndSetOrdered above.
|
// it changed after the testAndSetOrdered above.
|
||||||
|
if ((quint64(curValue) >> 32) == 0x7fffffff)
|
||||||
|
return false; // overflow!
|
||||||
curValue += oneWaiter;
|
curValue += oneWaiter;
|
||||||
|
|
||||||
// Also adjust valueToSubtract to subtract oneWaiter when we succeed in
|
// Also adjust nn to subtract oneWaiter when we succeed in acquiring.
|
||||||
// acquiring.
|
nn += oneWaiter;
|
||||||
valueToSubtract += oneWaiter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (futexSemaphoreTryAcquire_loop<IsTimed>(u, curValue, valueToSubtract, timeout))
|
if (futexSemaphoreTryAcquire_loop<IsTimed>(u, curValue, nn, timeout))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (futexHasWaiterCount) {
|
if (futexHasWaiterCount) {
|
||||||
@ -345,7 +349,10 @@ void QSemaphore::release(int n)
|
|||||||
Q_ASSERT_X(n >= 0, "QSemaphore::release", "parameter 'n' must be non-negative");
|
Q_ASSERT_X(n >= 0, "QSemaphore::release", "parameter 'n' must be non-negative");
|
||||||
|
|
||||||
if (futexAvailable()) {
|
if (futexAvailable()) {
|
||||||
quintptr prevValue = u.fetchAndAddRelease(n);
|
quintptr nn = unsigned(n);
|
||||||
|
if (futexHasWaiterCount)
|
||||||
|
nn |= quint64(nn) << 32; // token count replicated in high word
|
||||||
|
quintptr prevValue = u.fetchAndAddRelease(nn);
|
||||||
if (futexNeedsWake(prevValue)) {
|
if (futexNeedsWake(prevValue)) {
|
||||||
#ifdef FUTEX_OP
|
#ifdef FUTEX_OP
|
||||||
if (!futexHasWaiterCount) {
|
if (!futexHasWaiterCount) {
|
||||||
|
@ -824,7 +824,7 @@ void QCoreTextFontEngine::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, gl
|
|||||||
|
|
||||||
QFixed QCoreTextFontEngine::emSquareSize() const
|
QFixed QCoreTextFontEngine::emSquareSize() const
|
||||||
{
|
{
|
||||||
return QFixed::QFixed(int(CTFontGetUnitsPerEm(ctfont)));
|
return QFixed(int(CTFontGetUnitsPerEm(ctfont)));
|
||||||
}
|
}
|
||||||
|
|
||||||
QFontEngine *QCoreTextFontEngine::cloneWithSize(qreal pixelSize) const
|
QFontEngine *QCoreTextFontEngine::cloneWithSize(qreal pixelSize) const
|
||||||
|
@ -1161,23 +1161,19 @@ void QWindowsWindow::fireExpose(const QRegion ®ion, bool force)
|
|||||||
QWindowSystemInterface::handleExposeEvent(window(), region);
|
QWindowSystemInterface::handleExposeEvent(window(), region);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline QWindow *findTransientChild(const QWindow *parent)
|
|
||||||
{
|
|
||||||
foreach (QWindow *w, QGuiApplication::topLevelWindows())
|
|
||||||
if (w->transientParent() == parent)
|
|
||||||
return w;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QWindowsWindow::destroyWindow()
|
void QWindowsWindow::destroyWindow()
|
||||||
{
|
{
|
||||||
qCDebug(lcQpaWindows) << __FUNCTION__ << this << window() << m_data.hwnd;
|
qCDebug(lcQpaWindows) << __FUNCTION__ << this << window() << m_data.hwnd;
|
||||||
if (m_data.hwnd) { // Stop event dispatching before Window is destroyed.
|
if (m_data.hwnd) { // Stop event dispatching before Window is destroyed.
|
||||||
setFlag(WithinDestroy);
|
setFlag(WithinDestroy);
|
||||||
// Clear any transient child relationships as Windows will otherwise destroy them (QTBUG-35499, QTBUG-36666)
|
// Clear any transient child relationships as Windows will otherwise destroy them (QTBUG-35499, QTBUG-36666)
|
||||||
if (QWindow *transientChild = findTransientChild(window()))
|
const auto tlw = QGuiApplication::topLevelWindows();
|
||||||
if (QWindowsWindow *tw = QWindowsWindow::windowsWindowOf(transientChild))
|
for (QWindow *w : tlw) {
|
||||||
|
if (w->transientParent() == window()) {
|
||||||
|
if (QWindowsWindow *tw = QWindowsWindow::windowsWindowOf(w))
|
||||||
tw->updateTransientParent();
|
tw->updateTransientParent();
|
||||||
|
}
|
||||||
|
}
|
||||||
QWindowsContext *context = QWindowsContext::instance();
|
QWindowsContext *context = QWindowsContext::instance();
|
||||||
if (context->windowUnderMouse() == window())
|
if (context->windowUnderMouse() == window())
|
||||||
context->clearWindowUnderMouse();
|
context->clearWindowUnderMouse();
|
||||||
|
@ -504,38 +504,8 @@ bool RCCResourceLibrary::interpretResourceFile(QIODevice *inputDevice,
|
|||||||
if (QDir::isRelativePath(absFileName))
|
if (QDir::isRelativePath(absFileName))
|
||||||
absFileName.prepend(currentPath);
|
absFileName.prepend(currentPath);
|
||||||
QFileInfo file(absFileName);
|
QFileInfo file(absFileName);
|
||||||
if (!file.exists()) {
|
|
||||||
m_failedResources.push_back(absFileName);
|
|
||||||
const QString msg = QString::fromLatin1("RCC: Error in '%1': Cannot find file '%2'\n")
|
|
||||||
.arg(fname, fileName);
|
|
||||||
m_errorDevice->write(msg.toUtf8());
|
|
||||||
if (ignoreErrors)
|
|
||||||
continue;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
} else if (file.isFile()) {
|
|
||||||
const bool arc =
|
|
||||||
addFile(alias,
|
|
||||||
RCCFileInfo(alias.section(slash, -1),
|
|
||||||
file,
|
|
||||||
language,
|
|
||||||
country,
|
|
||||||
RCCFileInfo::NoFlags,
|
|
||||||
compressLevel,
|
|
||||||
compressThreshold)
|
|
||||||
);
|
|
||||||
if (!arc)
|
|
||||||
m_failedResources.push_back(absFileName);
|
|
||||||
} else {
|
|
||||||
QDir dir;
|
|
||||||
if (file.isDir()) {
|
if (file.isDir()) {
|
||||||
dir.setPath(file.filePath());
|
QDir dir(file.filePath());
|
||||||
} else {
|
|
||||||
dir.setPath(file.path());
|
|
||||||
dir.setNameFilters(QStringList(file.fileName()));
|
|
||||||
if (alias.endsWith(file.fileName()))
|
|
||||||
alias = alias.left(alias.length()-file.fileName().length());
|
|
||||||
}
|
|
||||||
if (!alias.endsWith(slash))
|
if (!alias.endsWith(slash))
|
||||||
alias += slash;
|
alias += slash;
|
||||||
QDirIterator it(dir, QDirIterator::FollowSymlinks|QDirIterator::Subdirectories);
|
QDirIterator it(dir, QDirIterator::FollowSymlinks|QDirIterator::Subdirectories);
|
||||||
@ -557,6 +527,33 @@ bool RCCResourceLibrary::interpretResourceFile(QIODevice *inputDevice,
|
|||||||
m_failedResources.push_back(child.fileName());
|
m_failedResources.push_back(child.fileName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (file.isFile()) {
|
||||||
|
const bool arc =
|
||||||
|
addFile(alias,
|
||||||
|
RCCFileInfo(alias.section(slash, -1),
|
||||||
|
file,
|
||||||
|
language,
|
||||||
|
country,
|
||||||
|
RCCFileInfo::NoFlags,
|
||||||
|
compressLevel,
|
||||||
|
compressThreshold)
|
||||||
|
);
|
||||||
|
if (!arc)
|
||||||
|
m_failedResources.push_back(absFileName);
|
||||||
|
} else if (file.exists()) {
|
||||||
|
m_failedResources.push_back(absFileName);
|
||||||
|
const QString msg = QString::fromLatin1("RCC: Error in '%1': Entry '%2' is neither a file nor a directory\n")
|
||||||
|
.arg(fname, fileName);
|
||||||
|
m_errorDevice->write(msg.toUtf8());
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
m_failedResources.push_back(absFileName);
|
||||||
|
const QString msg = QString::fromLatin1("RCC: Error in '%1': Cannot find file '%2'\n")
|
||||||
|
.arg(fname, fileName);
|
||||||
|
m_errorDevice->write(msg.toUtf8());
|
||||||
|
if (ignoreErrors)
|
||||||
|
continue;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2375,11 +2375,7 @@ void tst_qmakelib::addTestFunctions(const QString &qindir)
|
|||||||
QTest::newRow("include(): fail")
|
QTest::newRow("include(): fail")
|
||||||
<< "include(include/nope.pri): OK = 1"
|
<< "include(include/nope.pri): OK = 1"
|
||||||
<< "OK = UNDEF"
|
<< "OK = UNDEF"
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
<< "Cannot read " + m_indir + "/include/nope.pri: The system cannot find the file specified."
|
|
||||||
#else
|
|
||||||
<< "Cannot read " + m_indir + "/include/nope.pri: No such file or directory"
|
<< "Cannot read " + m_indir + "/include/nope.pri: No such file or directory"
|
||||||
#endif
|
|
||||||
<< true;
|
<< true;
|
||||||
|
|
||||||
QTest::newRow("include(): silent fail")
|
QTest::newRow("include(): silent fail")
|
||||||
@ -2873,12 +2869,12 @@ void tst_qmakelib::proEval()
|
|||||||
globals.environment = m_env;
|
globals.environment = m_env;
|
||||||
globals.setProperties(m_prop);
|
globals.setProperties(m_prop);
|
||||||
globals.setDirectories(m_indir, m_outdir);
|
globals.setDirectories(m_indir, m_outdir);
|
||||||
ProFile *outPro = parser.parsedProBlock(QStringRef(&out), "out", 1, QMakeParser::FullGrammar);
|
ProFile *outPro = parser.parsedProBlock(QStringRef(&out), 0, "out", 1, QMakeParser::FullGrammar);
|
||||||
if (!outPro->isOk()) {
|
if (!outPro->isOk()) {
|
||||||
qWarning("Expected output is malformed");
|
qWarning("Expected output is malformed");
|
||||||
verified = false;
|
verified = false;
|
||||||
}
|
}
|
||||||
ProFile *pro = parser.parsedProBlock(QStringRef(&in), infile, 1, QMakeParser::FullGrammar);
|
ProFile *pro = parser.parsedProBlock(QStringRef(&in), 0, infile, 1, QMakeParser::FullGrammar);
|
||||||
QMakeEvaluator visitor(&globals, &parser, &vfs, &handler);
|
QMakeEvaluator visitor(&globals, &parser, &vfs, &handler);
|
||||||
visitor.setOutputDir(m_outdir);
|
visitor.setOutputDir(m_outdir);
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
|
@ -2031,7 +2031,7 @@ void tst_qmakelib::proParser()
|
|||||||
handler.setExpectedMessages(msgs.split('\n', QString::SkipEmptyParts));
|
handler.setExpectedMessages(msgs.split('\n', QString::SkipEmptyParts));
|
||||||
QMakeVfs vfs;
|
QMakeVfs vfs;
|
||||||
QMakeParser parser(0, &vfs, &handler);
|
QMakeParser parser(0, &vfs, &handler);
|
||||||
ProFile *pro = parser.parsedProBlock(QStringRef(&in), "in", 1, QMakeParser::FullGrammar);
|
ProFile *pro = parser.parsedProBlock(QStringRef(&in), 0, "in", 1, QMakeParser::FullGrammar);
|
||||||
if (handler.printedMessages()) {
|
if (handler.printedMessages()) {
|
||||||
qWarning("Got unexpected message(s)");
|
qWarning("Got unexpected message(s)");
|
||||||
verified = false;
|
verified = false;
|
||||||
|
@ -281,7 +281,7 @@ void tst_QGraphicsProxyWidget::initTestCase()
|
|||||||
// This will be called after every test function.
|
// This will be called after every test function.
|
||||||
void tst_QGraphicsProxyWidget::cleanup()
|
void tst_QGraphicsProxyWidget::cleanup()
|
||||||
{
|
{
|
||||||
QVERIFY(QApplication::topLevelWidgets().isEmpty());
|
QTRY_VERIFY(QApplication::topLevelWidgets().isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QGraphicsProxyWidget::qgraphicsproxywidget_data()
|
void tst_QGraphicsProxyWidget::qgraphicsproxywidget_data()
|
||||||
@ -2575,6 +2575,22 @@ void tst_QGraphicsProxyWidget::changingCursor_basic()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static bool findViewAndTipLabel(const QWidget *view)
|
||||||
|
{
|
||||||
|
bool foundView = false;
|
||||||
|
bool foundTipLabel = false;
|
||||||
|
const QWidgetList &topLevels = QApplication::topLevelWidgets();
|
||||||
|
for (const QWidget *widget : topLevels) {
|
||||||
|
if (widget == view)
|
||||||
|
foundView = true;
|
||||||
|
if (widget->inherits("QTipLabel"))
|
||||||
|
foundTipLabel = true;
|
||||||
|
if (foundView && foundTipLabel)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void tst_QGraphicsProxyWidget::tooltip_basic()
|
void tst_QGraphicsProxyWidget::tooltip_basic()
|
||||||
{
|
{
|
||||||
QString toolTip = "Qt rocks!";
|
QString toolTip = "Qt rocks!";
|
||||||
@ -2627,18 +2643,7 @@ void tst_QGraphicsProxyWidget::tooltip_basic()
|
|||||||
QHelpEvent helpEvent(QEvent::ToolTip, view.mapFromScene(proxy->boundingRect().center()),
|
QHelpEvent helpEvent(QEvent::ToolTip, view.mapFromScene(proxy->boundingRect().center()),
|
||||||
view.viewport()->mapToGlobal(view.mapFromScene(proxy->boundingRect().center())));
|
view.viewport()->mapToGlobal(view.mapFromScene(proxy->boundingRect().center())));
|
||||||
QApplication::sendEvent(view.viewport(), &helpEvent);
|
QApplication::sendEvent(view.viewport(), &helpEvent);
|
||||||
QTest::qWait(350);
|
QTRY_VERIFY(findViewAndTipLabel(&view));
|
||||||
|
|
||||||
bool foundView = false;
|
|
||||||
bool foundTipLabel = false;
|
|
||||||
foreach (QWidget *widget, QApplication::topLevelWidgets()) {
|
|
||||||
if (widget == &view)
|
|
||||||
foundView = true;
|
|
||||||
if (widget->inherits("QTipLabel"))
|
|
||||||
foundTipLabel = true;
|
|
||||||
}
|
|
||||||
QVERIFY(foundView);
|
|
||||||
QVERIFY(foundTipLabel);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user