summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qcollator_win.cpp
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-03-14 01:00:21 +0100
committerEdward Welbourne <edward.welbourne@qt.io>2019-03-14 10:49:29 +0100
commit32084b073362e52df597cc388cf54f5173e20b0d (patch)
tree9a6f881f0ab0bc22e3a491fae81d494815cc514f /src/corelib/tools/qcollator_win.cpp
parent8d4e8217fdc01417ab8ea33303dd0ce7f769d10e (diff)
parenteb25acc05b177c49eb81b190a476854fbf3c6fb1 (diff)
Merge remote-tracking branch 'origin/5.13' into dev
Conflicts: src/corelib/tools/qcollator_win.cpp Change-Id: I6d806d7c58b2057ebde3ad915bb5551f34b700e5
Diffstat (limited to 'src/corelib/tools/qcollator_win.cpp')
-rw-r--r--src/corelib/tools/qcollator_win.cpp34
1 files changed, 28 insertions, 6 deletions
diff --git a/src/corelib/tools/qcollator_win.cpp b/src/corelib/tools/qcollator_win.cpp
index 4adbf4adf8..9d81de882f 100644
--- a/src/corelib/tools/qcollator_win.cpp
+++ b/src/corelib/tools/qcollator_win.cpp
@@ -72,6 +72,8 @@ void QCollatorPrivate::init()
if (caseSensitivity == Qt::CaseInsensitive)
collator |= NORM_IGNORECASE;
+ // WINE does not support SORT_DIGITSASNUMBERS :-(
+ // (and its std::sort() crashes on bad comparisons, QTBUG-74209)
if (numericMode)
collator |= SORT_DIGITSASNUMBERS;
@@ -98,16 +100,36 @@ int QCollator::compare(QStringView s1, QStringView s2) const
// runtime convention of comparing strings, the value 2 can be subtracted
// from a nonzero return value. Then, the meaning of <0, ==0, and >0 is
// consistent with the C runtime.
+ // [...] The function returns 0 if it does not succeed.
+ // https://docs.microsoft.com/en-us/windows/desktop/api/stringapiset/nf-stringapiset-comparestringex#return-value
#ifndef USE_COMPARESTRINGEX
- return CompareString(d->localeID, d->collator,
- reinterpret_cast<const wchar_t*>(s1.data()), s1.size(),
- reinterpret_cast<const wchar_t*>(s2.data()), s2.size()) - 2;
+ const int ret = CompareString(d->localeID, d->collator,
+ reinterpret_cast<const wchar_t *>(s1.data()), s1.size(),
+ reinterpret_cast<const wchar_t *>(s2.data()), s2.size());
#else
- return CompareStringEx(LPCWSTR(d->localeName.utf16()), d->collator,
- reinterpret_cast<LPCWSTR>(s1.data()), s1.size(),
- reinterpret_cast<LPCWSTR>(s2.data()), s2.size(), NULL, NULL, 0) - 2;
+ const int ret = CompareStringEx(LPCWSTR(d->localeName.utf16()), d->collator,
+ reinterpret_cast<LPCWSTR>(s1.data()), s1.size(),
+ reinterpret_cast<LPCWSTR>(s2.data()), s2.size(),
+ nullptr, nullptr, 0);
#endif
+ if (Q_LIKELY(ret))
+ return ret - 2;
+
+ switch (DWORD error = GetLastError()) {
+ case ERROR_INVALID_FLAGS:
+ qWarning("Unsupported flags (%d) used in QCollator", int(d->collator));
+ break;
+ case ERROR_INVALID_PARAMETER:
+ qWarning("Invalid parameter for QCollator::compare()");
+ break;
+ default:
+ qWarning("Failed (%ld) comparison in QCollator::compare()", long(error));
+ break;
+ }
+ // We have no idea what to return, so pretend we think they're equal.
+ // At least that way we'll be consistent if we get the same values swapped ...
+ return 0;
}
QCollatorSortKey QCollator::sortKey(const QString &string) const