diff --git a/mkspecs/android-clang/qmake.conf b/mkspecs/android-clang/qmake.conf index b25a4399f3..c33bbe7eed 100644 --- a/mkspecs/android-clang/qmake.conf +++ b/mkspecs/android-clang/qmake.conf @@ -1,4 +1,4 @@ -# qmake configuration for building with android-g++ +# qmake configuration for building with android-clang MAKEFILE_GENERATOR = UNIX QMAKE_PLATFORM = android QMAKE_COMPILER = gcc clang llvm diff --git a/mkspecs/win32-msvc2017/qmake.conf b/mkspecs/win32-msvc2017/qmake.conf new file mode 100644 index 0000000000..b8351eb3fe --- /dev/null +++ b/mkspecs/win32-msvc2017/qmake.conf @@ -0,0 +1,10 @@ +# +# qmake configuration for win32-msvc2017 +# +# Written for Microsoft Visual C++ 2017 +# + +MSC_VER = 1910 +MSVC_VER = 15.0 +include(../common/msvc-desktop.conf) +load(qt_config) diff --git a/mkspecs/win32-msvc2017/qplatformdefs.h b/mkspecs/win32-msvc2017/qplatformdefs.h new file mode 100644 index 0000000000..7100e3aa41 --- /dev/null +++ b/mkspecs/win32-msvc2017/qplatformdefs.h @@ -0,0 +1,34 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../win32-msvc2005/qplatformdefs.h" diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32 index 0a1f5529af..cd2cdd9c40 100644 --- a/qmake/Makefile.win32 +++ b/qmake/Makefile.win32 @@ -23,7 +23,7 @@ CXX = cl LINKER = link ! if "$(QMAKESPEC)" == "win32-msvc2013" CFLAGS_EXTRA = /MP /D_CRT_SECURE_NO_WARNINGS /D_SCL_SECURE_NO_WARNINGS $(CFLAGS_CRT) -! elseif "$(QMAKESPEC)" == "win32-msvc2015" || "$(QMAKESPEC)" == "win32-clang-msvc2015" +! elseif "$(QMAKESPEC)" == "win32-msvc2015" || "$(QMAKESPEC)" == "win32-msvc2017" || "$(QMAKESPEC)" == "win32-clang-msvc2015" CFLAGS_EXTRA = /MP /D_CRT_SECURE_NO_WARNINGS /D_SCL_SECURE_NO_WARNINGS /Zc:strictStrings /w44456 /w44457 /w44458 /wd4577 $(CFLAGS_CRT) ! else ! error Unsupported compiler for this Makefile diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc index aa6c8b35cc..c3c878ebb8 100644 --- a/qmake/doc/src/qmake-manual.qdoc +++ b/qmake/doc/src/qmake-manual.qdoc @@ -2057,6 +2057,12 @@ value of this variable is typically handled by qmake or \l{#QMAKESPEC}{qmake.conf} and rarely needs to be modified. + \section1 QMAKE_OBJECTIVE_CFLAGS + + Specifies the Objective C/C++ compiler flags for building + a project. These flags are used in addition to QMAKE_CFLAGS and + QMAKE_CXXFLAGS. + \section1 QMAKE_POST_LINK Specifies the command to execute after linking the \l{TARGET} diff --git a/qmake/generators/win32/msvc_objectmodel.h b/qmake/generators/win32/msvc_objectmodel.h index a744804760..e97996120f 100644 --- a/qmake/generators/win32/msvc_objectmodel.h +++ b/qmake/generators/win32/msvc_objectmodel.h @@ -52,7 +52,8 @@ enum DotNET { NET2010 = 0xa0, NET2012 = 0xb0, NET2013 = 0xc0, - NET2015 = 0xd0 + NET2015 = 0xd0, + NET2017 = 0xe0 }; /* diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index cb44937bea..7b3d7fd160 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -64,6 +64,7 @@ struct DotNetCombo { const char *versionStr; const char *regKey; } dotNetCombo[] = { + {NET2017, "MSVC.NET 2017 (15.0)", "Software\\Microsoft\\VisualStudio\\SxS\\VS7\\15.0"}, {NET2015, "MSVC.NET 2015 (14.0)", "Software\\Microsoft\\VisualStudio\\14.0\\Setup\\VC\\ProductDir"}, {NET2013, "MSVC.NET 2013 (12.0)", "Software\\Microsoft\\VisualStudio\\12.0\\Setup\\VC\\ProductDir"}, {NET2013, "MSVC.NET 2013 Express Edition (12.0)", "Software\\Microsoft\\VCExpress\\12.0\\Setup\\VC\\ProductDir"}, @@ -158,6 +159,8 @@ const char _slnHeader120[] = "Microsoft Visual Studio Solution File, Format "\n# Visual Studio 2013"; const char _slnHeader140[] = "Microsoft Visual Studio Solution File, Format Version 12.00" "\n# Visual Studio 2015"; +const char _slnHeader141[] = "Microsoft Visual Studio Solution File, Format Version 12.00" + "\n# Visual Studio 2017"; // The following UUID _may_ change for later servicepacks... // If so we need to search through the registry at // HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\7.0\Projects @@ -386,6 +389,8 @@ QString VcprojGenerator::retrievePlatformToolSet() const return QStringLiteral("v120") + suffix; case NET2015: return QStringLiteral("v140") + suffix; + case NET2017: + return QStringLiteral("v141") + suffix; default: return QString(); } @@ -613,6 +618,9 @@ void VcprojGenerator::writeSubDirs(QTextStream &t) } switch (which_dotnet_version(project->first("MSVC_VER").toLatin1())) { + case NET2017: + t << _slnHeader141; + break; case NET2015: t << _slnHeader140; break; @@ -934,6 +942,9 @@ void VcprojGenerator::initProject() // Own elements ----------------------------- vcProject.Name = project->first("QMAKE_ORIG_TARGET").toQString(); switch (which_dotnet_version(project->first("MSVC_VER").toLatin1())) { + case NET2017: + vcProject.Version = "15.00"; + break; case NET2015: vcProject.Version = "14.00"; break; diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp index 338131d06b..017fc3434c 100644 --- a/qmake/library/qmakeevaluator.cpp +++ b/qmake/library/qmakeevaluator.cpp @@ -971,6 +971,13 @@ static ProString msvcBinDirToQMakeArch(QString subdir) subdir = subdir.toLower(); if (subdir == QLatin1String("amd64")) return ProString("x86_64"); + // Since 2017 the folder structure from here is HostX64|X86/x64|x86 + idx = subdir.indexOf(QLatin1Char('\\')); + if (idx == -1) + return ProString("x86"); + subdir.remove(0, idx + 1); + if (subdir == QLatin1String("x64")) + return ProString("x86_64"); return ProString(subdir); } @@ -1065,8 +1072,12 @@ void QMakeEvaluator::loadDefaults() vars[ProKey("QMAKE_HOST.arch")] << archStr; # if defined(Q_CC_MSVC) // ### bogus condition, but nobody x-builds for msvc with a different qmake + // Since VS 2017 we need VCToolsInstallDir instead of VCINSTALLDIR + QString vcInstallDir = m_option->getEnv(QLatin1String("VCToolsInstallDir")); + if (vcInstallDir.isEmpty()) + vcInstallDir = m_option->getEnv(QLatin1String("VCINSTALLDIR")); vars[ProKey("QMAKE_TARGET.arch")] = msvcArchitecture( - m_option->getEnv(QLatin1String("VCINSTALLDIR")), + vcInstallDir, m_option->getEnv(QLatin1String("PATH"))); # endif #elif defined(Q_OS_UNIX) diff --git a/src/corelib/codecs/qsimplecodec_p.h b/src/corelib/codecs/qsimplecodec_p.h index d268a9f5b8..188c3f3cb4 100644 --- a/src/corelib/codecs/qsimplecodec_p.h +++ b/src/corelib/codecs/qsimplecodec_p.h @@ -67,12 +67,12 @@ public: explicit QSimpleTextCodec(int); ~QSimpleTextCodec(); - QString convertToUnicode(const char *, int, ConverterState *) const; - QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const; + QString convertToUnicode(const char *, int, ConverterState *) const override; + QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const override; - QByteArray name() const; - QList aliases() const; - int mibEnum() const; + QByteArray name() const override; + QList aliases() const override; + int mibEnum() const override; private: int forwardIndex; diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index 0b2345f8d4..d1d5373146 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -986,6 +986,9 @@ # define Q_COMPILER_THREADSAFE_STATICS # define Q_COMPILER_UNIFORM_INIT # endif +# if _MSC_VER >= 1910 +# define Q_COMPILER_CONSTEXPR +# endif # endif /* __cplusplus */ #endif /* Q_CC_MSVC */ diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index 1469f5776b..27fe10a79e 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -318,8 +318,10 @@ QLibraryInfo::buildDate() # define COMPILER_STRING "MSVC 2012" # elif _MSC_VER < 1900 # define COMPILER_STRING "MSVC 2013" -# elif _MSC_VER < 2000 +# elif _MSC_VER < 1910 # define COMPILER_STRING "MSVC 2015" +# elif _MSC_VER < 2000 +# define COMPILER_STRING "MSVC 2017" # else # define COMPILER_STRING "MSVC _MSC_VER " QT_STRINGIFY(_MSC_VER) # endif diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 0ca6829564..f344873276 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -1779,7 +1779,7 @@ void qErrnoWarning(int code, const char *msg, ...) \snippet code/src_corelib_global_qglobal.cpp 23 - \sa QtMessageHandler, QtMsgType, qDebug(), qWarning(), qCritical(), qFatal(), + \sa QtMessageHandler, QtMsgType, qDebug(), qInfo(), qWarning(), qCritical(), qFatal(), {Debugging Techniques} */ diff --git a/src/corelib/io/qfile_p.h b/src/corelib/io/qfile_p.h index fd7db3c120..545890c6b3 100644 --- a/src/corelib/io/qfile_p.h +++ b/src/corelib/io/qfile_p.h @@ -70,7 +70,7 @@ protected: bool openExternalFile(int flags, int fd, QFile::FileHandleFlags handleFlags); bool openExternalFile(int flags, FILE *fh, QFile::FileHandleFlags handleFlags); - virtual QAbstractFileEngine *engine() const; + QAbstractFileEngine *engine() const override; QString fileName; }; diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 5de85f9811..1b908eac55 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -65,6 +65,13 @@ #include #endif +#if defined(Q_OS_DARWIN) +// We cannot include (it's an Objective-C header), but +// we need these declarations: +Q_FORWARD_DECLARE_OBJC_CLASS(NSString); +extern "C" NSString *NSTemporaryDirectory(); +#endif + QT_BEGIN_NAMESPACE #if defined(Q_OS_DARWIN) @@ -703,8 +710,17 @@ QString QFileSystemEngine::tempPath() return QLatin1String(QT_UNIX_TEMP_PATH_OVERRIDE); #else QString temp = QFile::decodeName(qgetenv("TMPDIR")); - if (temp.isEmpty()) - temp = QLatin1String("/tmp"); + if (temp.isEmpty()) { +#if defined(Q_OS_DARWIN) && !defined(QT_BOOTSTRAPPED) + if (NSString *nsPath = NSTemporaryDirectory()) { + temp = QString::fromCFString((CFStringRef)nsPath); + } else { +#else + { +#endif + temp = QLatin1String("/tmp"); + } + } return QDir::cleanPath(temp); #endif } diff --git a/src/corelib/io/qtemporaryfile_p.h b/src/corelib/io/qtemporaryfile_p.h index d057603034..7f365f0e8a 100644 --- a/src/corelib/io/qtemporaryfile_p.h +++ b/src/corelib/io/qtemporaryfile_p.h @@ -70,7 +70,7 @@ protected: explicit QTemporaryFilePrivate(const QString &templateNameIn); ~QTemporaryFilePrivate(); - QAbstractFileEngine *engine() const; + QAbstractFileEngine *engine() const override; void resetFileEngine() const; bool autoRemove = true; @@ -99,14 +99,14 @@ public: ~QTemporaryFileEngine(); bool isReallyOpen() const; - void setFileName(const QString &file); + void setFileName(const QString &file) override; void setFileTemplate(const QString &fileTemplate); - bool open(QIODevice::OpenMode flags); - bool remove(); - bool rename(const QString &newName); - bool renameOverwrite(const QString &newName); - bool close(); + bool open(QIODevice::OpenMode flags) override; + bool remove() override; + bool rename(const QString &newName) override; + bool renameOverwrite(const QString &newName) override; + bool close() override; quint32 fileMode; bool filePathIsTemplate; diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index 5b34813a71..60ce752eb6 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -3690,6 +3690,9 @@ bool QUrl::matches(const QUrl &url, FormattingOptions options) const if ((d->sectionIsPresent & mask) != (url.d->sectionIsPresent & mask)) return false; + if (options & QUrl::RemovePath) + return true; + // Compare paths, after applying path-related options QString path1; d->appendPath(path1, options, QUrlPrivate::Path); diff --git a/src/corelib/mimetypes/qmimetypeparser_p.h b/src/corelib/mimetypes/qmimetypeparser_p.h index a502439419..0ce39e701c 100644 --- a/src/corelib/mimetypes/qmimetypeparser_p.h +++ b/src/corelib/mimetypes/qmimetypeparser_p.h @@ -108,19 +108,19 @@ public: explicit QMimeTypeParser(QMimeXMLProvider &provider) : m_provider(provider) {} protected: - inline bool process(const QMimeType &t, QString *) + inline bool process(const QMimeType &t, QString *) override { m_provider.addMimeType(t); return true; } - inline bool process(const QMimeGlobPattern &glob, QString *) + inline bool process(const QMimeGlobPattern &glob, QString *) override { m_provider.addGlobPattern(glob); return true; } - inline void processParent(const QString &child, const QString &parent) + inline void processParent(const QString &child, const QString &parent) override { m_provider.addParent(child, parent); } - inline void processAlias(const QString &alias, const QString &name) + inline void processAlias(const QString &alias, const QString &name) override { m_provider.addAlias(alias, name); } - inline void processMagicMatcher(const QMimeMagicRuleMatcher &matcher) + inline void processMagicMatcher(const QMimeMagicRuleMatcher &matcher) override { m_provider.addMagicMatcher(matcher); } private: diff --git a/src/corelib/statemachine/qhistorystate_p.h b/src/corelib/statemachine/qhistorystate_p.h index 4a4442d7dd..d22e5c4aaf 100644 --- a/src/corelib/statemachine/qhistorystate_p.h +++ b/src/corelib/statemachine/qhistorystate_p.h @@ -88,8 +88,8 @@ protected: // state, it will handle this transition as a special case. The history state itself is never // entered either: either the stored configuration will be used, or the target(s) of this // transition are used. - virtual bool eventTest(QEvent *event) { Q_UNUSED(event); return false; } - virtual void onTransition(QEvent *event) { Q_UNUSED(event); } + bool eventTest(QEvent *event) override { Q_UNUSED(event); return false; } + void onTransition(QEvent *event) override { Q_UNUSED(event); } }; QT_END_NAMESPACE diff --git a/src/corelib/thread/qbasicatomic.h b/src/corelib/thread/qbasicatomic.h index 447fca44c0..24218e833a 100644 --- a/src/corelib/thread/qbasicatomic.h +++ b/src/corelib/thread/qbasicatomic.h @@ -61,6 +61,9 @@ # error "Qt requires C++11 support" #endif +QT_WARNING_PUSH +QT_WARNING_DISABLE_MSVC(4522) + QT_BEGIN_NAMESPACE #if 0 @@ -323,4 +326,6 @@ public: QT_END_NAMESPACE +QT_WARNING_POP + #endif // QBASICATOMIC_H diff --git a/src/corelib/thread/qfutureinterface.cpp b/src/corelib/thread/qfutureinterface.cpp index ce31fe9270..c62b8fd36b 100644 --- a/src/corelib/thread/qfutureinterface.cpp +++ b/src/corelib/thread/qfutureinterface.cpp @@ -83,13 +83,33 @@ QFutureInterfaceBase::~QFutureInterfaceBase() delete d; } +static inline int switch_on(QAtomicInt &a, int which) +{ + return a.fetchAndOrRelaxed(which) | which; +} + +static inline int switch_off(QAtomicInt &a, int which) +{ + return a.fetchAndAndRelaxed(~which) & ~which; +} + +static inline int switch_from_to(QAtomicInt &a, int from, int to) +{ + int newValue; + int expected = a.load(); + do { + newValue = (expected & ~from) | to; + } while (!a.testAndSetRelaxed(expected, newValue, expected)); + return newValue; +} + void QFutureInterfaceBase::cancel() { QMutexLocker locker(&d->m_mutex); - if (d->state & Canceled) + if (d->state.load() & Canceled) return; - d->state = State((d->state & ~Paused) | Canceled); + switch_from_to(d->state, Paused, Canceled); d->waitCondition.wakeAll(); d->pausedWaitCondition.wakeAll(); d->sendCallOut(QFutureCallOutEvent(QFutureCallOutEvent::Canceled)); @@ -99,10 +119,10 @@ void QFutureInterfaceBase::setPaused(bool paused) { QMutexLocker locker(&d->m_mutex); if (paused) { - d->state = State(d->state | Paused); + switch_on(d->state, Paused); d->sendCallOut(QFutureCallOutEvent(QFutureCallOutEvent::Paused)); } else { - d->state = State(d->state & ~Paused); + switch_off(d->state, Paused); d->pausedWaitCondition.wakeAll(); d->sendCallOut(QFutureCallOutEvent(QFutureCallOutEvent::Resumed)); } @@ -111,29 +131,24 @@ void QFutureInterfaceBase::setPaused(bool paused) void QFutureInterfaceBase::togglePaused() { QMutexLocker locker(&d->m_mutex); - if (d->state & Paused) { - d->state = State(d->state & ~Paused); + if (d->state.load() & Paused) { + switch_off(d->state, Paused); d->pausedWaitCondition.wakeAll(); d->sendCallOut(QFutureCallOutEvent(QFutureCallOutEvent::Resumed)); } else { - d->state = State(d->state | Paused); + switch_on(d->state, Paused); d->sendCallOut(QFutureCallOutEvent(QFutureCallOutEvent::Paused)); } } void QFutureInterfaceBase::setThrottled(bool enable) { - // bail out if we are not changing the state - if ((enable && (d->state & Throttled)) || (!enable && !(d->state & Throttled))) - return; - - // lock and change the state QMutexLocker lock(&d->m_mutex); if (enable) { - d->state = State(d->state | Throttled); + switch_on(d->state, Throttled); } else { - d->state = State(d->state & ~Throttled); - if (!(d->state & Paused)) + switch_off(d->state, Throttled); + if (!(d->state.load() & Paused)) d->pausedWaitCondition.wakeAll(); } } @@ -184,11 +199,15 @@ bool QFutureInterfaceBase::waitForNextResult() void QFutureInterfaceBase::waitForResume() { // return early if possible to avoid taking the mutex lock. - if ((d->state & Paused) == false || (d->state & Canceled)) - return; + { + const int state = d->state.load(); + if (!(state & Paused) || (state & Canceled)) + return; + } QMutexLocker lock(&d->m_mutex); - if ((d->state & Paused) == false || (d->state & Canceled)) + const int state = d->state.load(); + if (!(state & Paused) || (state & Canceled)) return; // decrease active thread count since this thread will wait. @@ -236,7 +255,7 @@ bool QFutureInterfaceBase::isProgressUpdateNeeded() const void QFutureInterfaceBase::reportStarted() { QMutexLocker locker(&d->m_mutex); - if ((d->state & Started) || (d->state & Canceled) || (d->state & Finished)) + if (d->state.load() & (Started|Canceled|Finished)) return; d->setState(State(Started | Running)); @@ -252,11 +271,11 @@ void QFutureInterfaceBase::reportCanceled() void QFutureInterfaceBase::reportException(const QException &exception) { QMutexLocker locker(&d->m_mutex); - if ((d->state & Canceled) || (d->state & Finished)) + if (d->state.load() & (Canceled|Finished)) return; d->m_exceptionStore.setException(exception); - d->state = State(d->state | Canceled); + switch_on(d->state, Canceled); d->waitCondition.wakeAll(); d->pausedWaitCondition.wakeAll(); d->sendCallOut(QFutureCallOutEvent(QFutureCallOutEvent::Canceled)); @@ -266,8 +285,8 @@ void QFutureInterfaceBase::reportException(const QException &exception) void QFutureInterfaceBase::reportFinished() { QMutexLocker locker(&d->m_mutex); - if (!(d->state & Finished)) { - d->state = State((d->state & ~Running) | Finished); + if (!isFinished()) { + switch_from_to(d->state, Running, Finished); d->waitCondition.wakeAll(); d->sendCallOut(QFutureCallOutEvent(QFutureCallOutEvent::Finished)); } @@ -287,7 +306,7 @@ int QFutureInterfaceBase::expectedResultCount() bool QFutureInterfaceBase::queryState(State state) const { - return (d->state & state); + return d->state.load() & state; } void QFutureInterfaceBase::waitForResult(int resultIndex) @@ -295,7 +314,7 @@ void QFutureInterfaceBase::waitForResult(int resultIndex) d->m_exceptionStore.throwPossibleException(); QMutexLocker lock(&d->m_mutex); - if (!(d->state & Running)) + if (!isRunning()) return; lock.unlock(); @@ -305,11 +324,9 @@ void QFutureInterfaceBase::waitForResult(int resultIndex) lock.relock(); - if (d->state & Running) { - const int waitIndex = (resultIndex == -1) ? INT_MAX : resultIndex; - while ((d->state & Running) && d->internal_isResultReadyAt(waitIndex) == false) - d->waitCondition.wait(&d->m_mutex); - } + const int waitIndex = (resultIndex == -1) ? INT_MAX : resultIndex; + while (isRunning() && !d->internal_isResultReadyAt(waitIndex)) + d->waitCondition.wait(&d->m_mutex); d->m_exceptionStore.throwPossibleException(); } @@ -317,7 +334,7 @@ void QFutureInterfaceBase::waitForResult(int resultIndex) void QFutureInterfaceBase::waitForFinished() { QMutexLocker lock(&d->m_mutex); - const bool alreadyFinished = !(d->state & Running); + const bool alreadyFinished = !isRunning(); lock.unlock(); if (!alreadyFinished) { @@ -325,7 +342,7 @@ void QFutureInterfaceBase::waitForFinished() lock.relock(); - while (d->state & Running) + while (isRunning()) d->waitCondition.wait(&d->m_mutex); } @@ -334,7 +351,7 @@ void QFutureInterfaceBase::waitForFinished() void QFutureInterfaceBase::reportResultsReady(int beginIndex, int endIndex) { - if ((d->state & Canceled) || (d->state & Finished) || beginIndex == endIndex) + if (beginIndex == endIndex || (d->state.load() & (Canceled|Finished))) return; d->waitCondition.wakeAll(); @@ -396,7 +413,7 @@ void QFutureInterfaceBase::setProgressValueAndText(int progressValue, if (d->m_progressValue >= progressValue) return; - if ((d->state & Canceled) || (d->state & Finished)) + if (d->state.load() & (Canceled|Finished)) return; if (d->internal_updateProgress(progressValue, progressText)) { @@ -468,10 +485,10 @@ bool QFutureInterfaceBasePrivate::internal_waitForNextResult() if (m_results.hasNextResult()) return true; - while ((state & QFutureInterfaceBase::Running) && m_results.hasNextResult() == false) + while ((state.load() & QFutureInterfaceBase::Running) && m_results.hasNextResult() == false) waitCondition.wait(&m_mutex); - return (!(state & QFutureInterfaceBase::Canceled) && m_results.hasNextResult()); + return !(state.load() & QFutureInterfaceBase::Canceled) && m_results.hasNextResult(); } bool QFutureInterfaceBasePrivate::internal_updateProgress(int progress, @@ -494,16 +511,16 @@ bool QFutureInterfaceBasePrivate::internal_updateProgress(int progress, void QFutureInterfaceBasePrivate::internal_setThrottled(bool enable) { // bail out if we are not changing the state - if ((enable && (state & QFutureInterfaceBase::Throttled)) - || (!enable && !(state & QFutureInterfaceBase::Throttled))) + if ((enable && (state.load() & QFutureInterfaceBase::Throttled)) + || (!enable && !(state.load() & QFutureInterfaceBase::Throttled))) return; // change the state if (enable) { - state = QFutureInterfaceBase::State(state | QFutureInterfaceBase::Throttled); + switch_on(state, QFutureInterfaceBase::Throttled); } else { - state = QFutureInterfaceBase::State(state & ~QFutureInterfaceBase::Throttled); - if (!(state & QFutureInterfaceBase::Paused)) + switch_off(state, QFutureInterfaceBase::Throttled); + if (!(state.load() & QFutureInterfaceBase::Paused)) pausedWaitCondition.wakeAll(); } } @@ -538,7 +555,7 @@ void QFutureInterfaceBasePrivate::connectOutputInterface(QFutureCallOutInterface { QMutexLocker locker(&m_mutex); - if (state & QFutureInterfaceBase::Started) { + if (state.load() & QFutureInterfaceBase::Started) { interface->postCallOutEvent(QFutureCallOutEvent(QFutureCallOutEvent::Started)); interface->postCallOutEvent(QFutureCallOutEvent(QFutureCallOutEvent::ProgressRange, m_progressMinimum, @@ -558,13 +575,13 @@ void QFutureInterfaceBasePrivate::connectOutputInterface(QFutureCallOutInterface it.batchedAdvance(); } - if (state & QFutureInterfaceBase::Paused) + if (state.load() & QFutureInterfaceBase::Paused) interface->postCallOutEvent(QFutureCallOutEvent(QFutureCallOutEvent::Paused)); - if (state & QFutureInterfaceBase::Canceled) + if (state.load() & QFutureInterfaceBase::Canceled) interface->postCallOutEvent(QFutureCallOutEvent(QFutureCallOutEvent::Canceled)); - if (state & QFutureInterfaceBase::Finished) + if (state.load() & QFutureInterfaceBase::Finished) interface->postCallOutEvent(QFutureCallOutEvent(QFutureCallOutEvent::Finished)); outputConnections.append(interface); @@ -583,7 +600,7 @@ void QFutureInterfaceBasePrivate::disconnectOutputInterface(QFutureCallOutInterf void QFutureInterfaceBasePrivate::setState(QFutureInterfaceBase::State newState) { - state = newState; + state.store(newState); } QT_END_NAMESPACE diff --git a/src/corelib/thread/qfutureinterface_p.h b/src/corelib/thread/qfutureinterface_p.h index ee8dfe1354..cf882dd9b4 100644 --- a/src/corelib/thread/qfutureinterface_p.h +++ b/src/corelib/thread/qfutureinterface_p.h @@ -162,7 +162,7 @@ public: int m_progressValue; // TQ int m_progressMinimum; // TQ int m_progressMaximum; // TQ - QFutureInterfaceBase::State state; + QAtomicInt state; // reads and writes can happen unprotected, both must be atomic QElapsedTimer progressTime; QWaitCondition pausedWaitCondition; QtPrivate::ResultStoreBase m_results; diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp index 3271e2a8c4..621c877174 100644 --- a/src/corelib/tools/qdatetimeparser.cpp +++ b/src/corelib/tools/qdatetimeparser.cpp @@ -888,12 +888,12 @@ QDateTimeParser::StateNode QDateTimeParser::parse(QString &input, int &cursorPos State state = Acceptable; QDateTime newCurrentValue; - int pos = 0; bool conflicts = false; const int sectionNodesCount = sectionNodes.size(); QDTPDEBUG << "parse" << input; { + int pos = 0; int year, month, day; const QDate currentDate = currentValue.date(); const QTime currentTime = currentValue.time(); diff --git a/src/gui/image/qxbmhandler.cpp b/src/gui/image/qxbmhandler.cpp index eda816f0f2..19015c5dcd 100644 --- a/src/gui/image/qxbmhandler.cpp +++ b/src/gui/image/qxbmhandler.cpp @@ -124,17 +124,18 @@ static bool read_xbm_body(QIODevice *device, int w, int h, QImage *outImage) qint64 readBytes = 0; + char *p; + // scan for database - for (;;) { + do { if ((readBytes = device->readLine(buf, buflen)) <= 0) { // end of file return false; } buf[readBytes] = '\0'; - if (QByteArray::fromRawData(buf, readBytes).contains("0x")) - break; - } + p = strstr(buf, "0x"); + } while (!p); if (outImage->size() != QSize(w, h) || outImage->format() != QImage::Format_MonoLSB) { *outImage = QImage(w, h, QImage::Format_MonoLSB); @@ -148,7 +149,6 @@ static bool read_xbm_body(QIODevice *device, int w, int h, QImage *outImage) int x = 0, y = 0; uchar *b = outImage->scanLine(0); - char *p = buf + QByteArray::fromRawData(buf, readBytes).indexOf("0x"); w = (w+7)/8; // byte width while (y < h) { // for all encoded bytes... @@ -163,7 +163,8 @@ static bool read_xbm_body(QIODevice *device, int w, int h, QImage *outImage) } else { // read another line if ((readBytes = device->readLine(buf,buflen)) <= 0) // EOF ==> truncated image break; - p = buf + QByteArray::fromRawData(buf, readBytes).indexOf("0x"); + buf[readBytes] = '\0'; + p = strstr(buf, "0x"); } } diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp index d59bd63caf..a6bc7d4d9c 100644 --- a/src/gui/kernel/qkeysequence.cpp +++ b/src/gui/kernel/qkeysequence.cpp @@ -1528,7 +1528,9 @@ bool QKeySequence::isDetached() const If the key sequence has no keys, an empty string is returned. On \macos, the string returned resembles the sequence that is - shown in the menu bar. + shown in the menu bar if \a format is + QKeySequence::NativeText; otherwise, the string uses the + "portable" format, suitable for writing to a file. \sa fromString() */ diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp index 31d832a9ce..a0438bd458 100644 --- a/src/gui/text/qcssparser.cpp +++ b/src/gui/text/qcssparser.cpp @@ -2211,6 +2211,7 @@ void Parser::init(const QString &css, bool isFile) bool Parser::parse(StyleSheet *styleSheet, Qt::CaseSensitivity nameCaseSensitivity) { if (testTokenAndEndsWith(ATKEYWORD_SYM, QLatin1String("charset"))) { + while (test(S) || test(CDO) || test(CDC)) {} if (!next(STRING)) return false; if (!next(SEMICOLON)) return false; } diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index d2da24ca94..1c03bf516f 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -947,8 +947,8 @@ QFontEngine *loadSingleEngine(int script, return 0; } + engine->isSmoothlyScalable = style->smoothScalable; fontCache->insertEngine(key, engine); - return engine; } } @@ -973,6 +973,7 @@ QFontEngine *loadSingleEngine(int script, return 0; } + engine->isSmoothlyScalable = style->smoothScalable; fontCache->insertEngine(key, engine); if (Q_LIKELY(cacheForCommonScript && !engine->symbol)) { diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 74ea8d15b7..739319e5d4 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -257,6 +257,7 @@ QFontEngine::QFontEngine(Type type) cache_cost = 0; fsType = 0; symbol = false; + isSmoothlyScalable = false; glyphFormat = Format_None; m_subPixelPositionCount = 0; diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index 42610e9b70..c0e350f755 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -325,6 +325,7 @@ public: uint cache_cost; // amount of mem used in bytes by the font uint fsType : 16; bool symbol; + bool isSmoothlyScalable; struct KernPair { uint left_right; QFixed adjust; diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index d0b8bff7f9..8257eec9ea 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -358,25 +358,23 @@ bool QNativeSocketEngine::initialize(qintptr socketDescriptor, QAbstractSocket:: // Start processing incoming data if (d->socketType == QAbstractSocket::TcpSocket) { - HRESULT hr; - QEventDispatcherWinRT::runOnXamlThread([&hr, socket, socketState, this]() { - Q_D(QNativeSocketEngine); + HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([d, socket, socketState, this]() { ComPtr buffer; HRESULT hr = g->bufferFactory->Create(READ_BUFFER_SIZE, &buffer); - RETURN_OK_IF_FAILED("initialize(): Could not create buffer"); + RETURN_HR_IF_FAILED("initialize(): Could not create buffer"); ComPtr stream; hr = socket->get_InputStream(&stream); - RETURN_OK_IF_FAILED("initialize(): Could not obtain input stream"); + RETURN_HR_IF_FAILED("initialize(): Could not obtain input stream"); ComPtr readOp; hr = stream->ReadAsync(buffer.Get(), READ_BUFFER_SIZE, InputStreamOptions_Partial, readOp.GetAddressOf()); - RETURN_OK_IF_FAILED_WITH_ARGS("initialize(): Failed to read from the socket buffer (%s).", - socketDescription(this).constData()); + RETURN_HR_IF_FAILED_WITH_ARGS("initialize(): Failed to read from the socket buffer (%s).", + socketDescription(this).constData()); QMutexLocker locker(&d->readOperationsMutex); d->pendingReadOps.append(readOp); d->socketState = socketState; hr = readOp->put_Completed(Callback(d, &QNativeSocketEnginePrivate::handleReadyRead).Get()); - RETURN_OK_IF_FAILED_WITH_ARGS("initialize(): Failed to set socket read callback (%s).", - socketDescription(this).constData()); + RETURN_HR_IF_FAILED_WITH_ARGS("initialize(): Failed to set socket read callback (%s).", + socketDescription(this).constData()); return S_OK; }); if (FAILED(hr)) diff --git a/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp index 7c88c73cc2..8cf6660c44 100644 --- a/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp +++ b/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp @@ -188,7 +188,7 @@ QPlatformBackingStore *QEglFSIntegration::createPlatformBackingStore(QWindow *wi QPlatformWindow *QEglFSIntegration::createPlatformWindow(QWindow *window) const { - QWindowSystemInterface::flushWindowSystemEvents(); + QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); QEglFSWindow *w = qt_egl_device_integration()->createWindow(window); w->create(); if (window->type() != Qt::ToolTip) diff --git a/src/plugins/platforms/eglfs/api/qeglfswindow.cpp b/src/plugins/platforms/eglfs/api/qeglfswindow.cpp index e79b377d40..639fc56d2b 100644 --- a/src/plugins/platforms/eglfs/api/qeglfswindow.cpp +++ b/src/plugins/platforms/eglfs/api/qeglfswindow.cpp @@ -215,7 +215,7 @@ void QEglFSWindow::setVisible(bool visible) QWindowSystemInterface::handleExposeEvent(wnd, QRect(QPoint(0, 0), wnd->geometry().size())); if (visible) - QWindowSystemInterface::flushWindowSystemEvents(); + QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); } void QEglFSWindow::setGeometry(const QRect &r) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmaliintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmaliintegration.cpp index cd468c989f..8eb07d727b 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmaliintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmaliintegration.cpp @@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE -struct fbdev_window { +struct shadow_fbdev_window { unsigned short width; unsigned short height; }; @@ -91,7 +91,7 @@ EGLNativeWindowType QEglFSMaliIntegration::createNativeWindow(QPlatformWindow *w Q_UNUSED(window); Q_UNUSED(format); - fbdev_window *fbwin = reinterpret_cast(malloc(sizeof(fbdev_window))); + shadow_fbdev_window *fbwin = reinterpret_cast(malloc(sizeof(shadow_fbdev_window))); if (NULL == fbwin) return 0; diff --git a/src/widgets/accessible/itemviews.cpp b/src/widgets/accessible/itemviews.cpp index 09eba76fbd..db5af4fd7c 100644 --- a/src/widgets/accessible/itemviews.cpp +++ b/src/widgets/accessible/itemviews.cpp @@ -564,20 +564,8 @@ void QAccessibleTable::modelChange(QAccessibleTableModelChangeEvent *event) QAccessible::Id id = iter.value(); QAccessibleInterface *iface = QAccessible::accessibleInterface(id); Q_ASSERT(iface); - if (iface->role() == QAccessible::Cell || iface->role() == QAccessible::ListItem) { - Q_ASSERT(iface->tableCellInterface()); - QAccessibleTableCell *cell = static_cast(iface->tableCellInterface()); - if (event->modelChangeType() == QAccessibleTableModelChangeEvent::RowsInserted - && cell->m_index.row() >= event->firstRow()) { - int newRow = cell->m_index.row() + newRows; - cell->m_index = cell->m_index.sibling(newRow, cell->m_index.column()); - } else if (event->modelChangeType() == QAccessibleTableModelChangeEvent::ColumnsInserted - && cell->m_index.column() >= event->firstColumn()) { - int newColumn = cell->m_index.column() + newColumns; - cell->m_index = cell->m_index.sibling(cell->m_index.row(), newColumn); - } - } else if (event->modelChangeType() == QAccessibleTableModelChangeEvent::RowsInserted - && iface->role() == QAccessible::RowHeader) { + if (event->modelChangeType() == QAccessibleTableModelChangeEvent::RowsInserted + && iface->role() == QAccessible::RowHeader) { QAccessibleTableHeaderCell *cell = static_cast(iface); if (cell->index >= event->firstRow()) { cell->index += newRows; @@ -616,27 +604,11 @@ void QAccessibleTable::modelChange(QAccessibleTableModelChangeEvent *event) if (iface->role() == QAccessible::Cell || iface->role() == QAccessible::ListItem) { Q_ASSERT(iface->tableCellInterface()); QAccessibleTableCell *cell = static_cast(iface->tableCellInterface()); - if (event->modelChangeType() == QAccessibleTableModelChangeEvent::RowsRemoved) { - if (cell->m_index.row() < event->firstRow()) { - newCache.insert(indexOfChild(cell), id); - } else if (cell->m_index.row() > event->lastRow()) { - int newRow = cell->m_index.row() - deletedRows; - cell->m_index = cell->m_index.sibling(newRow, cell->m_index.column()); - newCache.insert(indexOfChild(cell), id); - } else { - QAccessible::deleteAccessibleInterface(id); - } - } else if (event->modelChangeType() == QAccessibleTableModelChangeEvent::ColumnsRemoved) { - if (cell->m_index.column() < event->firstColumn()) { - newCache.insert(indexOfChild(cell), id); - } else if (cell->m_index.column() > event->lastColumn()) { - int newColumn = cell->m_index.column() - deletedColumns; - cell->m_index = cell->m_index.sibling(cell->m_index.row(), newColumn); - newCache.insert(indexOfChild(cell), id); - } else { - QAccessible::deleteAccessibleInterface(id); - } - } + // Since it is a QPersistentModelIndex, we only need to check if it is valid + if (cell->m_index.isValid()) + newCache.insert(indexOfChild(cell), id); + else + QAccessible::deleteAccessibleInterface(id); } else if (event->modelChangeType() == QAccessibleTableModelChangeEvent::RowsRemoved && iface->role() == QAccessible::RowHeader) { QAccessibleTableHeaderCell *cell = static_cast(iface); diff --git a/src/widgets/accessible/itemviews_p.h b/src/widgets/accessible/itemviews_p.h index 5b73444c67..1b3869f2fa 100644 --- a/src/widgets/accessible/itemviews_p.h +++ b/src/widgets/accessible/itemviews_p.h @@ -216,7 +216,7 @@ private: QHeaderView *verticalHeader() const; QHeaderView *horizontalHeader() const; QPointer view; - QModelIndex m_index; + QPersistentModelIndex m_index; QAccessible::Role m_role; void selectCell(); diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp index dd5f5325b1..ffe1ca1c66 100644 --- a/src/widgets/widgets/qlineedit.cpp +++ b/src/widgets/widgets/qlineedit.cpp @@ -603,7 +603,7 @@ const QValidator * QLineEdit::validator() const The initial setting is to have no input validator (i.e. any input is accepted up to maxLength()). - \sa validator(), QIntValidator, QDoubleValidator, QRegExpValidator + \sa validator(), hasAcceptableInput(), QIntValidator, QDoubleValidator, QRegExpValidator */ void QLineEdit::setValidator(const QValidator *v) diff --git a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp index 5b18ab9d68..a7a761a2da 100644 --- a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp +++ b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp @@ -33,6 +33,9 @@ #include #include #include +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) && !defined(Q_OS_WINCE) +# include +#endif #ifdef Q_OS_UNIX #include @@ -126,6 +129,16 @@ static const char * const enumNames[MaxStandardLocation + 1 - int(QStandardPaths void tst_qstandardpaths::initTestCase() { +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) && !defined(Q_OS_WINCE) + // Disable WOW64 redirection, see testFindExecutable() + if (QSysInfo::buildCpuArchitecture() != QSysInfo::currentCpuArchitecture()) { + void *oldMode; + const bool disabledDisableWow64FsRedirection = Wow64DisableWow64FsRedirection(&oldMode) == TRUE; + if (!disabledDisableWow64FsRedirection) + qErrnoWarning("Wow64DisableWow64FsRedirection() failed"); + QVERIFY(disabledDisableWow64FsRedirection); + } +#endif // Q_OS_WIN && !Q_OS_WINRT && !Q_OS_WINCE QVERIFY2(m_localConfigTempDir.isValid(), qPrintable(m_localConfigTempDir.errorString())); QVERIFY2(m_globalConfigTempDir.isValid(), qPrintable(m_globalConfigTempDir.errorString())); QVERIFY2(m_localAppTempDir.isValid(), qPrintable(m_localAppTempDir.errorString())); @@ -375,6 +388,7 @@ void tst_qstandardpaths::testFindExecutable_data() if (QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS8) { // The logo executable on Windows 8 is perfectly suited for testing that the // suffix mechanism is not thrown off by dots in the name. + // Note: Requires disabling WOW64 redirection, see initTestCase() const QString logo = QLatin1String("microsoft.windows.softwarelogo.showdesktop"); const QString logoPath = cmdFi.absolutePath() + QLatin1Char('/') + logo + QLatin1String(".exe"); QTest::newRow("win8-logo") diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index f589fe1d6d..a4461a12d3 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -177,6 +177,8 @@ private slots: void streaming(); void detach(); void testThreading(); + void matches_data(); + void matches(); private: void testThreadingHelper(); @@ -4020,6 +4022,54 @@ void tst_QUrl::testThreading() delete s_urlStorage; } +void tst_QUrl::matches_data() +{ + QTest::addColumn("urlStrOne"); + QTest::addColumn("urlStrTwo"); + QTest::addColumn("options"); + QTest::addColumn("matches"); + + QTest::newRow("matchingString-none") << "http://www.website.com/directory/?#ref" + << "http://www.website.com/directory/?#ref" + << uint(QUrl::None) << true; + QTest::newRow("nonMatchingString-none") << "http://www.website.com/directory/?#ref" + << "http://www.nomatch.com/directory/?#ref" + << uint(QUrl::None) << false; + QTest::newRow("matchingHost-removePath") << "http://www.website.com/directory" + << "http://www.website.com/differentdir" + << uint(QUrl::RemovePath) << true; + QTest::newRow("nonMatchingHost-removePath") << "http://www.website.com/directory" + << "http://www.different.com/differentdir" + << uint(QUrl::RemovePath) << false; + QTest::newRow("matchingHost-removePathAuthority") << "http://user:pass@www.website.com/directory" + << "http://www.website.com/differentdir" + << uint(QUrl::RemovePath | QUrl::RemoveAuthority) + << true; + QTest::newRow("nonMatchingHost-removePathAuthority") << "http://user:pass@www.website.com/directory" + << "http://user:pass@www.different.com/differentdir" + << uint(QUrl::RemovePath | QUrl::RemoveAuthority) + << true; + QTest::newRow("matchingHostAuthority-removePathAuthority") + << "http://user:pass@www.website.com/directory" << "http://www.website.com/differentdir" + << uint(QUrl::RemovePath | QUrl::RemoveAuthority) << true; + QTest::newRow("nonMatchingAuthority-removePathAuthority") + << "http://user:pass@www.website.com/directory" + << "http://otheruser:otherpass@www.website.com/directory" + << uint(QUrl::RemovePath | QUrl::RemoveAuthority) << true; +} + +void tst_QUrl::matches() +{ + QFETCH(QString, urlStrOne); + QFETCH(QString, urlStrTwo); + QFETCH(uint, options); + QFETCH(bool, matches); + + QUrl urlOne(urlStrOne); + QUrl urlTwo(urlStrTwo); + QCOMPARE(urlOne.matches(urlTwo, QUrl::FormattingOptions(options)), matches); +} + QTEST_MAIN(tst_QUrl) #include "tst_qurl.moc" diff --git a/tests/auto/corelib/thread/qthread/tst_qthread.cpp b/tests/auto/corelib/thread/qthread/tst_qthread.cpp index 06b27f79cd..0efbc5d01e 100644 --- a/tests/auto/corelib/thread/qthread/tst_qthread.cpp +++ b/tests/auto/corelib/thread/qthread/tst_qthread.cpp @@ -1059,8 +1059,8 @@ void tst_QThread::wait2() thread.start(); timer.start(); QVERIFY(!thread.wait(Waiting_Thread::WaitTime)); - qint64 elapsed = timer.elapsed(); // On Windows, we sometimes get (WaitTime - 1). - QVERIFY2(elapsed >= Waiting_Thread::WaitTime - 1, qPrintable(QString::fromLatin1("elapsed: %1").arg(elapsed))); + qint64 elapsed = timer.elapsed(); // On Windows, we sometimes get (WaitTime - 9). + QVERIFY2(elapsed >= Waiting_Thread::WaitTime - 10, qPrintable(QString::fromLatin1("elapsed: %1").arg(elapsed))); timer.start(); thread.cond1.wakeOne(); diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp index 2f5936f1ad..11baee7335 100644 --- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp @@ -2897,7 +2897,10 @@ void tst_QAccessibility::listTest() QAccessibleInterface *cellMunich3 = table2->cellAt(2,0); QCOMPARE(cell4, cellMunich3); QCOMPARE(axidMunich, QAccessible::uniqueId(cellMunich3)); - + delete listView->takeItem(2); + // list: Oslo, Helsinki + // verify that it doesn't return an invalid item from the cache + QVERIFY(table2->cellAt(2,0) == 0); delete listView; } diff --git a/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp b/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp index a16bd1a787..1ff7a0c97b 100644 --- a/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp +++ b/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp @@ -340,8 +340,7 @@ void tst_QFileDialog2::task143519_deleteAndRenameActionBehavior() // test based on task233037_selectingDirectory struct TestContext { - TestContext() - : current(QDir::current()) {} + explicit TestContext(const QString &path) : current(path) {} ~TestContext() { file.remove(); current.rmdir(test.dirName()); @@ -349,7 +348,9 @@ void tst_QFileDialog2::task143519_deleteAndRenameActionBehavior() QDir current; QDir test; QFile file; - } ctx; + }; + + TestContext ctx(tempDir.path()); // setup testbed QVERIFY(ctx.current.mkdir("task143519_deleteAndRenameActionBehavior_test")); // ensure at least one item @@ -363,6 +364,7 @@ void tst_QFileDialog2::task143519_deleteAndRenameActionBehavior() QFileDialog fd; fd.setViewMode(QFileDialog::List); fd.setDirectory(ctx.test.absolutePath()); + fd.selectFile(ctx.file.fileName()); fd.show(); QTest::qWaitForWindowActive(&fd); @@ -377,7 +379,7 @@ void tst_QFileDialog2::task143519_deleteAndRenameActionBehavior() // defaults QVERIFY(openContextMenu(fd)); - QCOMPARE(fd.selectedFiles().size(), 1); + QCOMPARE(fd.selectedFiles(), QStringList(ctx.file.fileName())); QCOMPARE(rm->isEnabled(), !fd.isReadOnly()); QCOMPARE(mv->isEnabled(), !fd.isReadOnly()); diff --git a/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp b/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp index e8bd86bee5..f8ab64e4d6 100644 --- a/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp +++ b/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp @@ -1672,16 +1672,16 @@ void tst_QListWidget::mimeData() QMimeData *data; - QVERIFY(data = list.mimeData(tableWidgetItemList)); + QVERIFY((data = list.mimeData(tableWidgetItemList))); delete data; - QVERIFY(data = list.model()->mimeData(modelIndexList)); + QVERIFY((data = list.model()->mimeData(modelIndexList))); delete data; - QVERIFY(data = list.model()->mimeData(modelIndexList)); + QVERIFY((data = list.model()->mimeData(modelIndexList))); delete data; - QVERIFY(data = list.mimeData(tableWidgetItemList)); + QVERIFY((data = list.mimeData(tableWidgetItemList))); delete data; // check the saved data is actually the same diff --git a/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp b/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp index 8f871b03f6..a86ffbc30d 100644 --- a/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp +++ b/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp @@ -1520,16 +1520,16 @@ void tst_QTableWidget::mimeData() QMimeData *data; - QVERIFY(data = table.mimeData(tableWidgetItemList)); + QVERIFY((data = table.mimeData(tableWidgetItemList))); delete data; - QVERIFY(data = table.model()->mimeData(modelIndexList)); + QVERIFY((data = table.model()->mimeData(modelIndexList))); delete data; - QVERIFY(data = table.model()->mimeData(modelIndexList)); + QVERIFY((data = table.model()->mimeData(modelIndexList))); delete data; - QVERIFY(data = table.mimeData(tableWidgetItemList)); + QVERIFY((data = table.mimeData(tableWidgetItemList))); delete data; // check the saved data is actually the same diff --git a/tests/auto/widgets/kernel/qformlayout/tst_qformlayout.cpp b/tests/auto/widgets/kernel/qformlayout/tst_qformlayout.cpp index 01e3d7bac0..d8239b5a28 100644 --- a/tests/auto/widgets/kernel/qformlayout/tst_qformlayout.cpp +++ b/tests/auto/widgets/kernel/qformlayout/tst_qformlayout.cpp @@ -43,6 +43,10 @@ #include +// ItemRole has enumerators for numerical values 0..2, thus the only +// valid numerical values for storing into an ItemRole variable are 0..3: +Q_CONSTEXPR QFormLayout::ItemRole invalidRole = QFormLayout::ItemRole(3); + static inline void setFrameless(QWidget *w) { Qt::WindowFlags flags = w->windowFlags(); @@ -567,7 +571,7 @@ void tst_QFormLayout::insertRow_QWidget_QWidget() { int row = -1; - QFormLayout::ItemRole role = QFormLayout::ItemRole(-123); + QFormLayout::ItemRole role = invalidRole; layout->getWidgetPosition(lbl1, &row, &role); QCOMPARE(row, 0); QCOMPARE(int(role), int(QFormLayout::LabelRole)); @@ -575,7 +579,7 @@ void tst_QFormLayout::insertRow_QWidget_QWidget() { int row = -1; - QFormLayout::ItemRole role = QFormLayout::ItemRole(-123); + QFormLayout::ItemRole role = invalidRole; layout->getWidgetPosition(fld1, &row, &role); QCOMPARE(row, 0); QCOMPARE(int(role), int(QFormLayout::FieldRole)); @@ -636,7 +640,7 @@ void tst_QFormLayout::insertRow_QWidget_QLayout() { int row = -1; - QFormLayout::ItemRole role = QFormLayout::ItemRole(-123); + QFormLayout::ItemRole role = invalidRole; layout->getWidgetPosition(lbl1, &row, &role); QCOMPARE(row, 0); QCOMPARE(int(role), int(QFormLayout::LabelRole)); @@ -644,7 +648,7 @@ void tst_QFormLayout::insertRow_QWidget_QLayout() { int row = -1; - QFormLayout::ItemRole role = QFormLayout::ItemRole(-123); + QFormLayout::ItemRole role = invalidRole; layout->getLayoutPosition(fld1, &row, &role); QCOMPARE(row, 0); QCOMPARE(int(role), int(QFormLayout::FieldRole)); @@ -992,7 +996,7 @@ void tst_QFormLayout::setWidget() { int row = -1; - QFormLayout::ItemRole role = QFormLayout::ItemRole(-123); + QFormLayout::ItemRole role = invalidRole; layout.getWidgetPosition(&w1, &row, &role); QCOMPARE(row, 5); QCOMPARE(int(role), int(QFormLayout::LabelRole)); @@ -1000,7 +1004,7 @@ void tst_QFormLayout::setWidget() { int row = -1; - QFormLayout::ItemRole role = QFormLayout::ItemRole(-123); + QFormLayout::ItemRole role = invalidRole; layout.getWidgetPosition(&w2, &row, &role); QCOMPARE(row, 3); QCOMPARE(int(role), int(QFormLayout::FieldRole)); @@ -1008,7 +1012,7 @@ void tst_QFormLayout::setWidget() { int row = -1; - QFormLayout::ItemRole role = QFormLayout::ItemRole(-123); + QFormLayout::ItemRole role = invalidRole; layout.getWidgetPosition(&w3, &row, &role); QCOMPARE(row, 3); QCOMPARE(int(role), int(QFormLayout::LabelRole)); @@ -1016,18 +1020,20 @@ void tst_QFormLayout::setWidget() { int row = -1; - QFormLayout::ItemRole role = QFormLayout::ItemRole(-123); + QFormLayout::ItemRole role = invalidRole; layout.getWidgetPosition(&w4, &row, &role); + // not found QCOMPARE(row, -1); - QCOMPARE(int(role), -123); + QCOMPARE(int(role), int(invalidRole)); } { int row = -1; - QFormLayout::ItemRole role = QFormLayout::ItemRole(-123); + QFormLayout::ItemRole role = invalidRole; layout.getWidgetPosition(0, &row, &role); + // not found QCOMPARE(row, -1); - QCOMPARE(int(role), -123); + QCOMPARE(int(role), int(invalidRole)); } } @@ -1060,7 +1066,7 @@ void tst_QFormLayout::setLayout() { int row = -1; - QFormLayout::ItemRole role = QFormLayout::ItemRole(-123); + QFormLayout::ItemRole role = invalidRole; layout.getLayoutPosition(&l1, &row, &role); QCOMPARE(row, 5); QCOMPARE(int(role), int(QFormLayout::LabelRole)); @@ -1068,7 +1074,7 @@ void tst_QFormLayout::setLayout() { int row = -1; - QFormLayout::ItemRole role = QFormLayout::ItemRole(-123); + QFormLayout::ItemRole role = invalidRole; layout.getLayoutPosition(&l2, &row, &role); QCOMPARE(row, 3); QCOMPARE(int(role), int(QFormLayout::FieldRole)); @@ -1076,7 +1082,7 @@ void tst_QFormLayout::setLayout() { int row = -1; - QFormLayout::ItemRole role = QFormLayout::ItemRole(-123); + QFormLayout::ItemRole role = invalidRole; layout.getLayoutPosition(&l3, &row, &role); QCOMPARE(row, 3); QCOMPARE(int(role), int(QFormLayout::LabelRole)); @@ -1084,18 +1090,18 @@ void tst_QFormLayout::setLayout() { int row = -1; - QFormLayout::ItemRole role = QFormLayout::ItemRole(-123); + QFormLayout::ItemRole role = invalidRole; layout.getLayoutPosition(&l4, &row, &role); QCOMPARE(row, -1); - QCOMPARE(int(role), -123); + QCOMPARE(int(role), int(invalidRole)); } { int row = -1; - QFormLayout::ItemRole role = QFormLayout::ItemRole(-123); + QFormLayout::ItemRole role = invalidRole; layout.getLayoutPosition(0, &row, &role); QCOMPARE(row, -1); - QCOMPARE(int(role), -123); + QCOMPARE(int(role), int(invalidRole)); } } diff --git a/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp b/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp index 09ab20f7ca..9ab755c5f1 100644 --- a/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp +++ b/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp @@ -3710,7 +3710,7 @@ void tst_QDateTimeEdit::dateEditCorrectSectionSize() QTest::keyClick(&edit, keyPair.first, keyPair.second); QDateTimeEditPrivate* edit_d_ptr(static_cast(qt_widget_private(&edit))); - QCOMPARE(edit_d_ptr->text, expectedDisplayString); + QCOMPARE(edit_d_ptr->QDateTimeParser::displayText(), expectedDisplayString); } #endif diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 2e6ee2a681..841aa66b8f 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -453,7 +453,8 @@ void Configure::parseCmdLine() if (dictionary[ "QMAKESPEC" ].endsWith("-icc") || dictionary[ "QMAKESPEC" ].endsWith("-msvc2012") || dictionary[ "QMAKESPEC" ].endsWith("-msvc2013") || - dictionary[ "QMAKESPEC" ].endsWith("-msvc2015")) { + dictionary[ "QMAKESPEC" ].endsWith("-msvc2015") || + dictionary[ "QMAKESPEC" ].endsWith("-msvc2017")) { if (dictionary[ "MAKE" ].isEmpty()) dictionary[ "MAKE" ] = "nmake"; dictionary[ "QMAKEMAKEFILE" ] = "Makefile.win32"; } else if (dictionary[ "QMAKESPEC" ].startsWith(QLatin1String("win32-g++"))) { @@ -942,11 +943,6 @@ void Configure::configure() bool Configure::showLicense(QString orgLicenseFile) { - if (dictionary["LICENSE_CONFIRMED"] == "yes") { - cout << "You have already accepted the terms of the license." << endl << endl; - return true; - } - bool showGpl2 = true; QString licenseFile = orgLicenseFile; QString theLicense; @@ -1057,23 +1053,35 @@ void Configure::readLicense() } } if (hasOpenSource && openSource) { - cout << endl << "This is the " << dictionary["PLATFORM NAME"] << " Open Source Edition." << endl; + cout << endl << "This is the " << dictionary["PLATFORM NAME"] << " Open Source Edition." << endl << endl; dictionary["LICENSEE"] = "Open Source"; dictionary["EDITION"] = "OpenSource"; - cout << endl; - if (!showLicense(dictionary["LICENSE FILE"])) { - cout << "Configuration aborted since license was not accepted"; - dictionary["DONE"] = "error"; - return; - } } else if (openSource) { cout << endl << "Cannot find the GPL license files! Please download the Open Source version of the library." << endl; dictionary["DONE"] = "error"; return; + } else { + QString tpLicense = sourcePath + "/LICENSE.PREVIEW.COMMERCIAL"; + if (QFile::exists(tpLicense)) { + cout << endl << "This is the Qt Preview Edition." << endl << endl; + + dictionary["EDITION"] = "Preview"; + dictionary["LICENSE FILE"] = tpLicense; + } else { + Tools::checkLicense(dictionary, sourcePath, buildPath); + } } - else { - Tools::checkLicense(dictionary, sourcePath, buildPath); + + if (dictionary["LICENSE_CONFIRMED"] != "yes") { + if (!showLicense(dictionary["LICENSE FILE"])) { + cout << "Configuration aborted since license was not accepted" << endl; + dictionary["DONE"] = "error"; + return; + } + } else if (dictionary["LICHECK"].isEmpty()) { // licheck executable shows license + cout << "You have already accepted the terms of the license." << endl << endl; } + if (dictionary["BUILDTYPE"] == "none") { if (openSource) configCmdLine << "-opensource"; diff --git a/tools/configure/environment.cpp b/tools/configure/environment.cpp index 17f44c12f7..e585b16ea7 100644 --- a/tools/configure/environment.cpp +++ b/tools/configure/environment.cpp @@ -68,6 +68,7 @@ struct CompilerInfo{ {CC_MSVC2013, "Microsoft (R) Visual Studio 2013 C/C++ Compiler (12.0)", "Software\\Microsoft\\VisualStudio\\SxS\\VC7\\12.0", "cl.exe"}, // link.exe, lib.exe // Microsoft skipped version 13 {CC_MSVC2015, "Microsoft (R) Visual Studio 2015 C/C++ Compiler (14.0)", "Software\\Microsoft\\VisualStudio\\SxS\\VS7\\14.0", "cl.exe"}, // link.exe, lib.exe + {CC_MSVC2017, "Microsoft (R) Visual Studio 2017 C/C++ Compiler (15.0)", "Software\\Microsoft\\VisualStudio\\SxS\\VS7\\15.0", "cl.exe"}, // link.exe, lib.exe {CC_UNKNOWN, "Unknown", 0, 0}, }; @@ -93,6 +94,9 @@ QString Environment::detectQMakeSpec() { QString spec; switch (detectCompiler()) { + case CC_MSVC2017: + spec = "win32-msvc2017"; + break; case CC_MSVC2015: spec = "win32-msvc2015"; break; diff --git a/tools/configure/environment.h b/tools/configure/environment.h index 2ab5b00d1c..aa8e7fd8bc 100644 --- a/tools/configure/environment.h +++ b/tools/configure/environment.h @@ -40,7 +40,8 @@ enum Compiler { CC_MSVC2010 = 0xA0, CC_MSVC2012 = 0xB0, CC_MSVC2013 = 0xC0, - CC_MSVC2015 = 0xD0 + CC_MSVC2015 = 0xD0, + CC_MSVC2017 = 0xE0 }; struct CompilerInfo; diff --git a/tools/configure/tools.cpp b/tools/configure/tools.cpp index fb80e2136b..5ba7125975 100644 --- a/tools/configure/tools.cpp +++ b/tools/configure/tools.cpp @@ -42,13 +42,6 @@ using namespace std; void Tools::checkLicense(QMap &dictionary, const QString &sourcePath, const QString &buildPath) { - QString tpLicense = sourcePath + "/LICENSE.PREVIEW.COMMERCIAL"; - if (QFile::exists(tpLicense)) { - dictionary["EDITION"] = "Preview"; - dictionary["LICENSE FILE"] = tpLicense; - return; - } - dictionary["LICHECK"] = "licheck.exe"; const QString licenseChecker = @@ -75,6 +68,7 @@ void Tools::checkLicense(QMap &dictionary, } else { foreach (const QString &var, licheckOutput.split('\n')) dictionary[var.section('=', 0, 0).toUpper()] = var.section('=', 1, 1); + dictionary["LICENSE_CONFIRMED"] = "yes"; } } else { cout << endl << "Error: Could not find licheck.exe" << endl