summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2017-03-28 09:23:03 +0200
committerLiang Qi <liang.qi@qt.io>2017-03-28 09:28:31 +0200
commitb48a13fd6843e12b5725aa3ff0d010007e7c43b4 (patch)
tree316cfe36fc67906efcd92ff806c7c0da56ed4f8e /src/corelib
parent3398d9d40cb0dae2dc2a1a4f7dc3b4b9cceae903 (diff)
parent15fe60cfdada84ea519f08e905d59cc3fb6d20cd (diff)
Merge remote-tracking branch 'origin/5.9' into dev
Conflicts: examples/examples.pro tests/auto/corelib/tools/qchar/tst_qchar.cpp tests/auto/other/qaccessibility/accessiblewidgets.h Change-Id: I426696c40ab57d14dc295b8103152cede79f244c
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/arch/qatomic_cxx11.h8
-rw-r--r--src/corelib/global/qnamespace.qdoc4
-rw-r--r--src/corelib/io/qdir.cpp47
-rw-r--r--src/corelib/io/qfsfileengine_unix.cpp15
-rw-r--r--src/corelib/io/qlockfile.cpp3
-rw-r--r--src/corelib/io/qlockfile_unix.cpp2
-rw-r--r--src/corelib/io/qlockfile_win.cpp2
-rw-r--r--src/corelib/io/qstandardpaths_mac.mm5
-rw-r--r--src/corelib/io/qstandardpaths_unix.cpp2
-rw-r--r--src/corelib/io/qstorageinfo_unix.cpp2
-rw-r--r--src/corelib/io/qurl.cpp11
-rw-r--r--src/corelib/json/qjsonwriter.cpp9
-rw-r--r--src/corelib/kernel/kernel.pri3
-rw-r--r--src/corelib/kernel/qcoreevent.cpp1
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp15
-rw-r--r--src/corelib/kernel/qmetatype.cpp6
-rw-r--r--src/corelib/tools/qchar.cpp4
-rw-r--r--src/corelib/tools/qchar.h26
-rw-r--r--src/corelib/tools/qdatetimeparser.cpp154
-rw-r--r--src/corelib/tools/qhash.cpp2
-rw-r--r--src/corelib/tools/qhash.h1
-rw-r--r--src/corelib/tools/qmap.h1
-rw-r--r--src/corelib/tools/qvarlengtharray.h1
23 files changed, 176 insertions, 148 deletions
diff --git a/src/corelib/arch/qatomic_cxx11.h b/src/corelib/arch/qatomic_cxx11.h
index 63b23b71ab..484ec73e7f 100644
--- a/src/corelib/arch/qatomic_cxx11.h
+++ b/src/corelib/arch/qatomic_cxx11.h
@@ -278,7 +278,7 @@ template <typename X> struct QAtomicOps
template <typename T>
static bool testAndSetRelaxed(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = Q_NULLPTR) Q_DECL_NOTHROW
{
- bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_relaxed);
+ bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_relaxed, std::memory_order_relaxed);
if (currentValue)
*currentValue = expectedValue;
return tmp;
@@ -287,7 +287,7 @@ template <typename X> struct QAtomicOps
template <typename T>
static bool testAndSetAcquire(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = Q_NULLPTR) Q_DECL_NOTHROW
{
- bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_acquire);
+ bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_acquire, std::memory_order_acquire);
if (currentValue)
*currentValue = expectedValue;
return tmp;
@@ -296,7 +296,7 @@ template <typename X> struct QAtomicOps
template <typename T>
static bool testAndSetRelease(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = Q_NULLPTR) Q_DECL_NOTHROW
{
- bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_release);
+ bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_release, std::memory_order_relaxed);
if (currentValue)
*currentValue = expectedValue;
return tmp;
@@ -305,7 +305,7 @@ template <typename X> struct QAtomicOps
template <typename T>
static bool testAndSetOrdered(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = Q_NULLPTR) Q_DECL_NOTHROW
{
- bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_acq_rel);
+ bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_acq_rel, std::memory_order_acquire);
if (currentValue)
*currentValue = expectedValue;
return tmp;
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index c44e95a84b..cd60774ee6 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -1168,8 +1168,8 @@
and Windows) the window will take a modified appearance. This flag is set
or cleared by QWidget::setWindowModified().
- \value WA_WindowPropagation Makes a toplevel window inherit font and
- palette from its parent.
+ \value WA_WindowPropagation Makes a toplevel window inherit font, palette
+ and locale from its parent.
\value WA_MacAlwaysShowToolWindow On \macos, show the tool window even
when the application is not active. By default, all tool windows are
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index bfb91c131f..6d144cb65d 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -2105,11 +2105,11 @@ Q_AUTOTEST_EXPORT QString qt_normalizePathSegments(const QString &name, bool all
return name;
int i = len - 1;
- QVarLengthArray<QChar> outVector(len);
+ QVarLengthArray<ushort> outVector(len);
int used = len;
- QChar *out = outVector.data();
- const QChar *p = name.unicode();
- const QChar *prefix = p;
+ ushort *out = outVector.data();
+ const ushort *p = name.utf16();
+ const ushort *prefix = p;
int up = 0;
const int prefixLength = rootLength(name, allowUncPaths);
@@ -2117,39 +2117,39 @@ Q_AUTOTEST_EXPORT QString qt_normalizePathSegments(const QString &name, bool all
i -= prefixLength;
// replicate trailing slash (i > 0 checks for emptiness of input string p)
- if (i > 0 && p[i].unicode() == '/') {
- out[--used].unicode() = '/';
+ if (i > 0 && p[i] == '/') {
+ out[--used] = '/';
--i;
}
while (i >= 0) {
// remove trailing slashes
- if (p[i].unicode() == '/') {
+ if (p[i] == '/') {
--i;
continue;
}
// remove current directory
- if (p[i].unicode() == '.' && (i == 0 || p[i-1].unicode() == '/')) {
+ if (p[i] == '.' && (i == 0 || p[i-1] == '/')) {
--i;
continue;
}
// detect up dir
- if (i >= 1 && p[i].unicode() == '.' && p[i-1].unicode() == '.'
- && (i == 1 || (i >= 2 && p[i-2].unicode() == '/'))) {
+ if (i >= 1 && p[i] == '.' && p[i-1] == '.'
+ && (i == 1 || (i >= 2 && p[i-2] == '/'))) {
++up;
i -= 2;
continue;
}
// prepend a slash before copying when not empty
- if (!up && used != len && out[used].unicode() != '/')
- out[--used] = QLatin1Char('/');
+ if (!up && used != len && out[used] != '/')
+ out[--used] = '/';
// skip or copy
while (i >= 0) {
- if (p[i].unicode() == '/') { // do not copy slashes
+ if (p[i] == '/') { // do not copy slashes
--i;
break;
}
@@ -2171,17 +2171,17 @@ Q_AUTOTEST_EXPORT QString qt_normalizePathSegments(const QString &name, bool all
// add remaining '..'
while (up) {
- if (used != len && out[used].unicode() != '/') // is not empty and there isn't already a '/'
- out[--used] = QLatin1Char('/');
- out[--used] = QLatin1Char('.');
- out[--used] = QLatin1Char('.');
+ if (used != len && out[used] != '/') // is not empty and there isn't already a '/'
+ out[--used] = '/';
+ out[--used] = '.';
+ out[--used] = '.';
--up;
}
bool isEmpty = used == len;
if (prefixLength) {
- if (!isEmpty && out[used].unicode() == '/') {
+ if (!isEmpty && out[used] == '/') {
// Eventhough there is a prefix the out string is a slash. This happens, if the input
// string only consists of a prefix followed by one or more slashes. Just skip the slash.
++used;
@@ -2192,18 +2192,19 @@ Q_AUTOTEST_EXPORT QString qt_normalizePathSegments(const QString &name, bool all
if (isEmpty) {
// After resolving the input path, the resulting string is empty (e.g. "foo/.."). Return
// a dot in that case.
- out[--used] = QLatin1Char('.');
- } else if (out[used].unicode() == '/') {
+ out[--used] = '.';
+ } else if (out[used] == '/') {
// After parsing the input string, out only contains a slash. That happens whenever all
// parts are resolved and there is a trailing slash ("./" or "foo/../" for example).
// Prepend a dot to have the correct return value.
- out[--used] = QLatin1Char('.');
+ out[--used] = '.';
}
}
// If path was not modified return the original value
- QString ret = (used == 0 ? name : QString(out + used, len - used));
- return ret;
+ if (used == 0)
+ return name;
+ return QString::fromUtf16(out + used, len - used);
}
static QString qt_cleanPath(const QString &path, bool *ok)
diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp
index ff77278dc1..4be4e893b3 100644
--- a/src/corelib/io/qfsfileengine_unix.cpp
+++ b/src/corelib/io/qfsfileengine_unix.cpp
@@ -688,6 +688,19 @@ QDateTime QFSFileEngine::fileTime(FileTime time) const
uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFlags flags)
{
+#if (defined(Q_OS_LINUX) || defined(Q_OS_ANDROID)) && Q_PROCESSOR_WORDSIZE == 4
+ // The Linux mmap2 system call on 32-bit takes a page-shifted 32-bit
+ // integer so the maximum offset is 1 << (32+12) (the shift is always 12,
+ // regardless of the actual page size). Unfortunately, the mmap64()
+ // function is known to be broken in all Linux libcs (glibc, uclibc, musl
+ // and Bionic): all of them do the right shift, but don't confirm that the
+ // result fits into the 32-bit parameter to the kernel.
+
+ static qint64 MaxFileOffset = (Q_INT64_C(1) << (32+12)) - 1;
+#else
+ static qint64 MaxFileOffset = std::numeric_limits<QT_OFF_T>::max();
+#endif
+
Q_Q(QFSFileEngine);
Q_UNUSED(flags);
if (openMode == QIODevice::NotOpen) {
@@ -695,7 +708,7 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFla
return 0;
}
- if (offset < 0 || offset != qint64(QT_OFF_T(offset))
+ if (offset < 0 || offset > MaxFileOffset
|| size < 0 || quint64(size) > quint64(size_t(-1))) {
q->setError(QFile::UnspecifiedError, qt_error_string(int(EINVAL)));
return 0;
diff --git a/src/corelib/io/qlockfile.cpp b/src/corelib/io/qlockfile.cpp
index cb1ff93ad3..48317d07e0 100644
--- a/src/corelib/io/qlockfile.cpp
+++ b/src/corelib/io/qlockfile.cpp
@@ -44,6 +44,7 @@
#include <QtCore/qthread.h>
#include <QtCore/qdeadlinetimer.h>
#include <QtCore/qdatetime.h>
+#include <QtCore/qfileinfo.h>
QT_BEGIN_NAMESPACE
@@ -226,6 +227,8 @@ bool QLockFile::tryLock(int timeout)
return false;
case LockFailedError:
if (!d->isLocked && d->isApparentlyStale()) {
+ if (Q_UNLIKELY(QFileInfo(d->fileName).lastModified() > QDateTime::currentDateTime()))
+ qInfo("QLockFile: Lock file '%ls' has a modification time in the future", qUtf16Printable(d->fileName));
// Stale lock from another thread/process
// Ensure two processes don't remove it at the same time
QLockFile rmlock(d->fileName + QLatin1String(".rmlock"));
diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp
index 3a80014c00..5a02741727 100644
--- a/src/corelib/io/qlockfile_unix.cpp
+++ b/src/corelib/io/qlockfile_unix.cpp
@@ -247,7 +247,7 @@ bool QLockFilePrivate::isApparentlyStale() const
}
}
const qint64 age = QFileInfo(fileName).lastModified().msecsTo(QDateTime::currentDateTime());
- return staleLockTime > 0 && age > staleLockTime;
+ return staleLockTime > 0 && qAbs(age) > staleLockTime;
}
QString QLockFilePrivate::processNameByPid(qint64 pid)
diff --git a/src/corelib/io/qlockfile_win.cpp b/src/corelib/io/qlockfile_win.cpp
index baaff8da17..4b43181686 100644
--- a/src/corelib/io/qlockfile_win.cpp
+++ b/src/corelib/io/qlockfile_win.cpp
@@ -160,7 +160,7 @@ bool QLockFilePrivate::isApparentlyStale() const
Q_UNUSED(appname);
#endif // Q_OS_WINRT
const qint64 age = QFileInfo(fileName).lastModified().msecsTo(QDateTime::currentDateTime());
- return staleLockTime > 0 && age > staleLockTime;
+ return staleLockTime > 0 && qAbs(age) > staleLockTime;
}
QString QLockFilePrivate::processNameByPid(qint64 pid)
diff --git a/src/corelib/io/qstandardpaths_mac.mm b/src/corelib/io/qstandardpaths_mac.mm
index a293d4862f..e25339a7d1 100644
--- a/src/corelib/io/qstandardpaths_mac.mm
+++ b/src/corelib/io/qstandardpaths_mac.mm
@@ -204,13 +204,14 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
CFBundleRef mainBundle = CFBundleGetMainBundle();
if (mainBundle) {
CFURLRef bundleUrl = CFBundleCopyBundleURL(mainBundle);
- CFStringRef cfBundlePath = CFURLCopyPath(bundleUrl);
+ CFStringRef cfBundlePath = CFURLCopyFileSystemPath(bundleUrl, kCFURLPOSIXPathStyle);
QString bundlePath = QString::fromCFString(cfBundlePath);
CFRelease(cfBundlePath);
CFRelease(bundleUrl);
CFURLRef resourcesUrl = CFBundleCopyResourcesDirectoryURL(mainBundle);
- CFStringRef cfResourcesPath = CFURLCopyPath(resourcesUrl);
+ CFStringRef cfResourcesPath = CFURLCopyFileSystemPath(resourcesUrl,
+ kCFURLPOSIXPathStyle);
QString resourcesPath = QString::fromCFString(cfResourcesPath);
CFRelease(cfResourcesPath);
CFRelease(resourcesUrl);
diff --git a/src/corelib/io/qstandardpaths_unix.cpp b/src/corelib/io/qstandardpaths_unix.cpp
index 7974dc8cca..f0ff46fe7f 100644
--- a/src/corelib/io/qstandardpaths_unix.cpp
+++ b/src/corelib/io/qstandardpaths_unix.cpp
@@ -117,7 +117,7 @@ QString QStandardPaths::writableLocation(StandardLocation type)
}
case RuntimeLocation:
{
- const uid_t myUid = geteuid();
+ const uint myUid = uint(geteuid());
// http://standards.freedesktop.org/basedir-spec/latest/
QFileInfo fileInfo;
QString xdgRuntimeDir = QFile::decodeName(qgetenv("XDG_RUNTIME_DIR"));
diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp
index fcc7b8ca50..b9c9883609 100644
--- a/src/corelib/io/qstorageinfo_unix.cpp
+++ b/src/corelib/io/qstorageinfo_unix.cpp
@@ -503,6 +503,8 @@ static QByteArray extractSubvolume(const QStorageIterator &it)
// if we didn't find the subvolume name, return the subvolume ID
return id;
}
+#else
+ Q_UNUSED(it);
#endif
return QByteArray();
}
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index 18ad59f1cb..b5772b5ce2 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -4169,12 +4169,15 @@ QUrl QUrl::fromUserInput(const QString &userInput, const QString &workingDirecto
return url;
}
+ const QFileInfo fileInfo(QDir(workingDirectory), userInput);
+ if (fileInfo.exists()) {
+ return QUrl::fromLocalFile(fileInfo.absoluteFilePath());
+ }
+
QUrl url = QUrl(userInput, QUrl::TolerantMode);
// Check both QUrl::isRelative (to detect full URLs) and QDir::isAbsolutePath (since on Windows drive letters can be interpreted as schemes)
- if (url.isRelative() && !QDir::isAbsolutePath(userInput)) {
- QFileInfo fileInfo(QDir(workingDirectory), userInput);
- if ((options & AssumeLocalFile) || fileInfo.exists())
- return QUrl::fromLocalFile(fileInfo.absoluteFilePath());
+ if ((options & AssumeLocalFile) && url.isRelative() && !QDir::isAbsolutePath(userInput)) {
+ return QUrl::fromLocalFile(fileInfo.absoluteFilePath());
}
return fromUserInput(trimmedString);
diff --git a/src/corelib/json/qjsonwriter.cpp b/src/corelib/json/qjsonwriter.cpp
index b1544c749d..12ce20ef09 100644
--- a/src/corelib/json/qjsonwriter.cpp
+++ b/src/corelib/json/qjsonwriter.cpp
@@ -38,6 +38,7 @@
**
****************************************************************************/
+#include <cmath>
#include <qlocale.h>
#include "qjsonwriter_p.h"
#include "qjson_p.h"
@@ -129,10 +130,12 @@ static void valueToJson(const QJsonPrivate::Base *b, const QJsonPrivate::Value &
break;
case QJsonValue::Double: {
const double d = v.toDouble(b);
- if (qIsFinite(d)) // +2 to format to ensure the expected precision
- json += QByteArray::number(d, 'g', QLocale::FloatingPointShortest);
- else
+ if (qIsFinite(d)) { // +2 to format to ensure the expected precision
+ const double abs = std::abs(d);
+ json += QByteArray::number(d, abs == static_cast<quint64>(abs) ? 'f' : 'g', QLocale::FloatingPointShortest);
+ } else {
json += "null"; // +INF || -INF || NaN (see RFC4627#section2.4)
+ }
break;
}
case QJsonValue::String:
diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri
index 461fbd7840..0e6ff17b8f 100644
--- a/src/corelib/kernel/kernel.pri
+++ b/src/corelib/kernel/kernel.pri
@@ -175,6 +175,9 @@ unix|integrity {
SOURCES += kernel/qsharedmemory_android.cpp \
kernel/qsystemsemaphore_android.cpp
}
+
+ # This is needed by QMetaType::typeName array implementation
+ integrity: QMAKE_CXXFLAGS += --pending_instantiations=128
}
vxworks {
diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp
index 64e73d23c5..4efc38ac89 100644
--- a/src/corelib/kernel/qcoreevent.cpp
+++ b/src/corelib/kernel/qcoreevent.cpp
@@ -216,6 +216,7 @@ QT_BEGIN_NAMESPACE
\omitvalue OkRequest
\value TabletEnterProximity Wacom tablet enter proximity event (QTabletEvent), sent to QApplication.
\value TabletLeaveProximity Wacom tablet leave proximity event (QTabletEvent), sent to QApplication.
+ \value TabletTrackingChange The Wacom tablet tracking state has changed (since Qt 5.9).
\omitvalue ThemeChange
\value ThreadChange The object is moved to another thread. This is the last event sent to this object in the previous thread. See QObject::moveToThread().
\value Timer Regular timer events (QTimerEvent).
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index 79146dac34..74fa2d8d50 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -407,7 +407,9 @@ void QEventDispatcherWin32Private::unregisterTimer(WinTimerInfo *t)
} else if (internalHwnd) {
KillTimer(internalHwnd, t->timerId);
}
- delete t;
+ t->timerId = -1;
+ if (!t->inTimerEvent)
+ delete t;
}
void QEventDispatcherWin32Private::sendTimerEvent(int timerId)
@@ -424,8 +426,9 @@ void QEventDispatcherWin32Private::sendTimerEvent(int timerId)
QCoreApplication::sendEvent(t->obj, &e);
// timer could have been removed
- t = timerDict.value(timerId);
- if (t) {
+ if (t->timerId == -1) {
+ delete t;
+ } else {
t->inTimerEvent = false;
}
}
@@ -1013,8 +1016,10 @@ bool QEventDispatcherWin32::event(QEvent *e)
QTimerEvent te(zte->timerId());
QCoreApplication::sendEvent(t->obj, &te);
- t = d->timerDict.value(zte->timerId());
- if (t) {
+ // timer could have been removed
+ if (t->timerId == -1) {
+ delete t;
+ } else {
if (t->interval == 0 && t->inTimerEvent) {
// post the next zero timer event as long as the timer was not restarted
QCoreApplication::postEvent(this, new QZeroTimerEvent(zte->timerId()));
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index 38e0d6055c..fc8d7dcfea 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -1341,7 +1341,6 @@ bool QMetaType::save(QDataStream &stream, int type, const void *data)
case QMetaType::UnknownType:
case QMetaType::Void:
case QMetaType::VoidStar:
- case QMetaType::Nullptr:
case QMetaType::QObjectStar:
case QMetaType::QModelIndex:
case QMetaType::QPersistentModelIndex:
@@ -1350,6 +1349,8 @@ bool QMetaType::save(QDataStream &stream, int type, const void *data)
case QMetaType::QJsonArray:
case QMetaType::QJsonDocument:
return false;
+ case QMetaType::Nullptr:
+ return true;
case QMetaType::Long:
stream << qlonglong(*static_cast<const long *>(data));
break;
@@ -1563,7 +1564,6 @@ bool QMetaType::load(QDataStream &stream, int type, void *data)
case QMetaType::UnknownType:
case QMetaType::Void:
case QMetaType::VoidStar:
- case QMetaType::Nullptr:
case QMetaType::QObjectStar:
case QMetaType::QModelIndex:
case QMetaType::QPersistentModelIndex:
@@ -1572,6 +1572,8 @@ bool QMetaType::load(QDataStream &stream, int type, void *data)
case QMetaType::QJsonArray:
case QMetaType::QJsonDocument:
return false;
+ case QMetaType::Nullptr:
+ return true;
case QMetaType::Long: {
qlonglong l;
stream >> l;
diff --git a/src/corelib/tools/qchar.cpp b/src/corelib/tools/qchar.cpp
index db440390c1..085adb1859 100644
--- a/src/corelib/tools/qchar.cpp
+++ b/src/corelib/tools/qchar.cpp
@@ -642,9 +642,9 @@ QT_BEGIN_NAMESPACE
Constructs a QChar corresponding to ASCII/Latin-1 character \a ch.
\note This constructor is not available when \c QT_NO_CAST_FROM_ASCII
- is defined.
+ or QT_RESTRICTED_CAST_FROM_ASCII is defined.
- \sa QT_NO_CAST_FROM_ASCII
+ \sa QT_NO_CAST_FROM_ASCII, QT_RESTRICTED_CAST_FROM_ASCII
*/
/*!
diff --git a/src/corelib/tools/qchar.h b/src/corelib/tools/qchar.h
index 8509e2e182..a1d31f6a68 100644
--- a/src/corelib/tools/qchar.h
+++ b/src/corelib/tools/qchar.h
@@ -585,17 +585,21 @@ Q_DECL_CONSTEXPR inline bool operator>=(QChar c1, QChar c2) Q_DECL_NOTHROW { ret
Q_DECL_CONSTEXPR inline bool operator> (QChar c1, QChar c2) Q_DECL_NOTHROW { return operator< (c2, c1); }
Q_DECL_CONSTEXPR inline bool operator<=(QChar c1, QChar c2) Q_DECL_NOTHROW { return !operator< (c2, c1); }
-// disambiguate QChar == int (but only that, so constrain template to exactly 'int'):
-template <typename T>
-Q_DECL_DEPRECATED_X("don't compare ints to QChars, compare them to QChar::unicode() instead")
-Q_DECL_CONSTEXPR inline
-typename std::enable_if<std::is_same<typename std::remove_cv<T>::type, int>::value, bool>::type
-operator==(QChar lhs, T rhs) Q_DECL_NOEXCEPT { return lhs == QChar(rhs); }
-template <typename T>
-Q_DECL_DEPRECATED_X("don't compare ints to QChars, compare them to QChar::unicode() instead")
-Q_DECL_CONSTEXPR inline
-typename std::enable_if<std::is_same<typename std::remove_cv<T>::type, int>::value, bool>::type
-operator!=(QChar lhs, T rhs) Q_DECL_NOEXCEPT { return lhs != QChar(rhs); }
+
+Q_DECL_CONSTEXPR inline bool operator==(QChar lhs, std::nullptr_t) Q_DECL_NOTHROW { return lhs.isNull(); }
+Q_DECL_CONSTEXPR inline bool operator< (QChar, std::nullptr_t) Q_DECL_NOTHROW { return false; }
+Q_DECL_CONSTEXPR inline bool operator==(std::nullptr_t, QChar rhs) Q_DECL_NOTHROW { return rhs.isNull(); }
+Q_DECL_CONSTEXPR inline bool operator< (std::nullptr_t, QChar rhs) Q_DECL_NOTHROW { return !rhs.isNull(); }
+
+Q_DECL_CONSTEXPR inline bool operator!=(QChar lhs, std::nullptr_t) Q_DECL_NOTHROW { return !operator==(lhs, nullptr); }
+Q_DECL_CONSTEXPR inline bool operator>=(QChar lhs, std::nullptr_t) Q_DECL_NOTHROW { return !operator< (lhs, nullptr); }
+Q_DECL_CONSTEXPR inline bool operator> (QChar lhs, std::nullptr_t) Q_DECL_NOTHROW { return operator< (nullptr, lhs); }
+Q_DECL_CONSTEXPR inline bool operator<=(QChar lhs, std::nullptr_t) Q_DECL_NOTHROW { return !operator< (nullptr, lhs); }
+
+Q_DECL_CONSTEXPR inline bool operator!=(std::nullptr_t, QChar rhs) Q_DECL_NOTHROW { return !operator==(nullptr, rhs); }
+Q_DECL_CONSTEXPR inline bool operator>=(std::nullptr_t, QChar rhs) Q_DECL_NOTHROW { return !operator< (nullptr, rhs); }
+Q_DECL_CONSTEXPR inline bool operator> (std::nullptr_t, QChar rhs) Q_DECL_NOTHROW { return operator< (rhs, nullptr); }
+Q_DECL_CONSTEXPR inline bool operator<=(std::nullptr_t, QChar rhs) Q_DECL_NOTHROW { return !operator< (rhs, nullptr); }
#ifndef QT_NO_DATASTREAM
Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, QChar);
diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp
index c8aa4fbc89..62dd25e072 100644
--- a/src/corelib/tools/qdatetimeparser.cpp
+++ b/src/corelib/tools/qdatetimeparser.cpp
@@ -1243,6 +1243,49 @@ end:
#endif // QT_NO_DATESTRING
#ifndef QT_NO_TEXTDATE
+
+/*
+ \internal
+ \brief Returns the index in \a entries with the best prefix match to \a text
+
+ Scans \a entries looking for an entry overlapping \a text as much as possible
+ (an exact match beats any prefix match; a match of the full entry as prefix of
+ text beats any entry but one matching a longer prefix; otherwise, the match of
+ longest prefix wins, earlier entries beating later on a draw). Records the
+ length of overlap in *used (if \a used is non-NULL) and the first entry that
+ overlapped this much in *usedText (if \a usedText is non-NULL).
+ */
+static int findTextEntry(const QString &text, const QVector<QString> &entries, QString *usedText, int *used)
+{
+ if (text.isEmpty())
+ return -1;
+
+ int bestMatch = -1;
+ int bestCount = 0;
+ for (int n = 0; n < entries.size(); ++n)
+ {
+ const QString &name = entries.at(n);
+
+ const int limit = qMin(text.size(), name.size());
+ int i = 0;
+ while (i < limit && text.at(i) == name.at(i).toLower())
+ ++i;
+ // Full match beats an equal prefix match:
+ if (i > bestCount || (i == bestCount && i == name.size())) {
+ bestCount = i;
+ bestMatch = n;
+ if (i == name.size() && i == text.size())
+ break; // Exact match, name == text, wins.
+ }
+ }
+ if (usedText && bestMatch != -1)
+ *usedText = entries.at(bestMatch);
+ if (used)
+ *used = bestCount;
+
+ return bestMatch;
+}
+
/*!
\internal
finds the first possible monthname that \a str1 can
@@ -1252,99 +1295,40 @@ end:
int QDateTimeParser::findMonth(const QString &str1, int startMonth, int sectionIndex,
QString *usedMonth, int *used) const
{
- int bestMatch = -1;
- int bestCount = 0;
- if (!str1.isEmpty()) {
- const SectionNode &sn = sectionNode(sectionIndex);
- if (sn.type != MonthSection) {
- qWarning("QDateTimeParser::findMonth Internal error");
- return -1;
- }
-
- QLocale::FormatType type = sn.count == 3 ? QLocale::ShortFormat : QLocale::LongFormat;
- QLocale l = locale();
+ const SectionNode &sn = sectionNode(sectionIndex);
+ if (sn.type != MonthSection) {
+ qWarning("QDateTimeParser::findMonth Internal error");
+ return -1;
+ }
- for (int month=startMonth; month<=12; ++month) {
- const QString monthName = l.monthName(month, type);
- QString str2 = monthName.toLower();
+ QLocale::FormatType type = sn.count == 3 ? QLocale::ShortFormat : QLocale::LongFormat;
+ QLocale l = locale();
+ QVector<QString> monthNames;
+ monthNames.reserve(13 - startMonth);
+ for (int month = startMonth; month <= 12; ++month)
+ monthNames.append(l.monthName(month, type));
- if (str1.startsWith(str2)) {
- if (used) {
- QDTPDEBUG << "used is set to" << str2.size();
- *used = str2.size();
- }
- if (usedMonth)
- *usedMonth = monthName;
-
- return month;
- }
- if (context == FromString)
- continue;
-
- const int limit = qMin(str1.size(), str2.size());
-
- QDTPDEBUG << "limit is" << limit << str1 << str2;
- bool equal = true;
- for (int i=0; i<limit; ++i) {
- if (str1.at(i) != str2.at(i)) {
- equal = false;
- if (i > bestCount) {
- bestCount = i;
- bestMatch = month;
- }
- break;
- }
- }
- if (equal) {
- if (used)
- *used = limit;
- if (usedMonth)
- *usedMonth = monthName;
- return month;
- }
- }
- if (usedMonth && bestMatch != -1)
- *usedMonth = l.monthName(bestMatch, type);
- }
- if (used) {
- QDTPDEBUG << "used is set to" << bestCount;
- *used = bestCount;
- }
- return bestMatch;
+ const int index = findTextEntry(str1, monthNames, usedMonth, used);
+ return index < 0 ? index : index + startMonth;
}
int QDateTimeParser::findDay(const QString &str1, int startDay, int sectionIndex, QString *usedDay, int *used) const
{
- int bestMatch = -1;
- int bestCount = 0;
- if (!str1.isEmpty()) {
- const SectionNode &sn = sectionNode(sectionIndex);
- if (!(sn.type & DaySectionMask)) {
- qWarning("QDateTimeParser::findDay Internal error");
- return -1;
- }
- const QLocale l = locale();
- for (int day=startDay; day<=7; ++day) {
- const QString dayName = l.dayName(day, sn.count == 4 ? QLocale::LongFormat : QLocale::ShortFormat);
- const QString str2 = dayName.toLower();
-
- const int limit = qMin(str1.size(), str2.size());
- int i = 0;
- while (i < limit && str1.at(i) == str2.at(i))
- ++i;
- if (i > bestCount) {
- bestCount = i;
- bestMatch = day;
- }
- }
- if (usedDay && bestMatch != -1) {
- *usedDay = l.dayName(bestMatch, sn.count == 4 ? QLocale::LongFormat : QLocale::ShortFormat);
- }
+ const SectionNode &sn = sectionNode(sectionIndex);
+ if (!(sn.type & DaySectionMask)) {
+ qWarning("QDateTimeParser::findDay Internal error");
+ return -1;
}
- if (used)
- *used = bestCount;
- return bestMatch;
+ QLocale::FormatType type = sn.count == 4 ? QLocale::LongFormat : QLocale::ShortFormat;
+ QLocale l = locale();
+ QVector<QString> daysOfWeek;
+ daysOfWeek.reserve(8 - startDay);
+ for (int day = startDay; day <= 7; ++day)
+ daysOfWeek.append(l.dayName(day, type));
+
+ const int index = findTextEntry(str1, daysOfWeek, usedDay, used);
+ return index < 0 ? index : index + startDay;
}
#endif // QT_NO_TEXTDATE
diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp
index 9270539f4f..334bd52f1e 100644
--- a/src/corelib/tools/qhash.cpp
+++ b/src/corelib/tools/qhash.cpp
@@ -325,7 +325,7 @@ static uint qt_create_qhash_seed()
/*
The QHash seed itself.
*/
-Q_CORE_EXPORT QBasicAtomicInt qt_qhash_seed = Q_BASIC_ATOMIC_INITIALIZER(-1);
+static QBasicAtomicInt qt_qhash_seed = Q_BASIC_ATOMIC_INITIALIZER(-1);
/*!
\internal
diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h
index 66b5e75a1a..c59f789cb2 100644
--- a/src/corelib/tools/qhash.h
+++ b/src/corelib/tools/qhash.h
@@ -432,6 +432,7 @@ public:
typedef const Key *pointer;
typedef const Key &reference;
+ key_iterator() = default;
explicit key_iterator(const_iterator o) : i(o) { }
const Key &operator*() const { return i.key(); }
diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h
index e6da2820f8..3ee6ab8c58 100644
--- a/src/corelib/tools/qmap.h
+++ b/src/corelib/tools/qmap.h
@@ -531,6 +531,7 @@ public:
typedef const Key *pointer;
typedef const Key &reference;
+ key_iterator() = default;
explicit key_iterator(const_iterator o) : i(o) { }
const Key &operator*() const { return i.key(); }
diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h
index c73d6bfa43..9879d55967 100644
--- a/src/corelib/tools/qvarlengtharray.h
+++ b/src/corelib/tools/qvarlengtharray.h
@@ -357,6 +357,7 @@ Q_OUTOFLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::realloc(int asize, int a
int osize = s;
const int copySize = qMin(asize, osize);
+ Q_ASSUME(copySize >= 0);
if (aalloc != a) {
if (aalloc > Prealloc) {
T* newPtr = reinterpret_cast<T *>(malloc(aalloc * sizeof(T)));