summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorThomas Zander <t.zander@nokia.com>2010-09-28 11:44:45 (GMT)
committerThomas Zander <t.zander@nokia.com>2010-09-28 11:44:45 (GMT)
commit5c08412285f14d89174aef1190a1de1c35fd62bd (patch)
tree2e9bef2fdf0af18db76b011cd9c4ed4b456f507c /src/corelib
parent2645784f05db7b1e631621c511e94c88fc5cd211 (diff)
parent2868302626b8a31f44df1068514485a89ec27171 (diff)
downloadQt-5c08412285f14d89174aef1190a1de1c35fd62bd.zip
Qt-5c08412285f14d89174aef1190a1de1c35fd62bd.tar.gz
Qt-5c08412285f14d89174aef1190a1de1c35fd62bd.tar.bz2
Merge commit 'origin/master' into fileEnginesOn47
Conflicts: qmake/Makefile.win32 qmake/qmake.pri src/corelib/io/qdir.cpp src/corelib/io/qfileinfo.cpp src/corelib/io/qfileinfo_p.h src/corelib/io/qfsfileengine_win.cpp src/s60installs/bwins/QtGuiu.def src/s60installs/eabi/QtCoreu.def src/s60installs/eabi/QtGuiu.def src/tools/bootstrap/bootstrap.pro tests/auto/qfileinfo/tst_qfileinfo.cpp
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/arch/arch.pri2
-rw-r--r--src/corelib/arch/armv6/arch.pri3
-rw-r--r--src/corelib/arch/qatomic_arm.h403
-rw-r--r--src/corelib/arch/qatomic_armv5.h431
-rw-r--r--src/corelib/arch/qatomic_armv6.h161
-rw-r--r--src/corelib/arch/qatomic_armv7.h61
-rw-r--r--src/corelib/arch/symbian/arch.pri2
-rw-r--r--src/corelib/arch/symbian/qatomic_generic_armv6.cpp (renamed from src/corelib/arch/armv6/qatomic_generic_armv6.cpp)0
-rw-r--r--src/corelib/codecs/qtextcodec_symbian.cpp25
-rw-r--r--src/corelib/concurrent/qfuturewatcher.cpp9
-rw-r--r--src/corelib/concurrent/qtconcurrentrun.cpp2
-rw-r--r--src/corelib/concurrent/qthreadpool.cpp1
-rw-r--r--src/corelib/global/global.pri2
-rw-r--r--src/corelib/global/qglobal.cpp2
-rw-r--r--src/corelib/global/qglobal.h41
-rw-r--r--src/corelib/global/qlibraryinfo.cpp15
-rw-r--r--src/corelib/global/qnamespace.h1
-rw-r--r--src/corelib/global/qnumeric.cpp35
-rw-r--r--src/corelib/io/qdir.cpp2
-rw-r--r--src/corelib/io/qdir.h4
-rw-r--r--src/corelib/io/qfileinfo.h4
-rw-r--r--src/corelib/io/qfilesystemengine_win.cpp6
-rw-r--r--src/corelib/io/qiodevice.cpp12
-rw-r--r--src/corelib/io/qprocess_symbian.cpp47
-rw-r--r--src/corelib/io/qsettings.cpp6
-rw-r--r--src/corelib/io/qsettings_win.cpp24
-rw-r--r--src/corelib/io/qurl.cpp52
-rw-r--r--src/corelib/io/qurl.h4
-rw-r--r--src/corelib/kernel/qabstractitemmodel.cpp40
-rw-r--r--src/corelib/kernel/qabstractitemmodel_p.h19
-rw-r--r--src/corelib/kernel/qcore_symbian_p.cpp8
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp3
-rw-r--r--src/corelib/kernel/qeventdispatcher_symbian.cpp8
-rw-r--r--src/corelib/kernel/qeventdispatcher_unix.cpp22
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp29
-rw-r--r--src/corelib/kernel/qmath.qdoc155
-rw-r--r--src/corelib/kernel/qmetaobject.cpp20
-rw-r--r--src/corelib/kernel/qmetatype.h26
-rw-r--r--src/corelib/kernel/qobject.h8
-rw-r--r--src/corelib/kernel/qobjectdefs.h1
-rw-r--r--src/corelib/kernel/qpointer.cpp2
-rw-r--r--src/corelib/kernel/qvariant.h4
-rw-r--r--src/corelib/plugin/plugin.pri11
-rw-r--r--src/corelib/plugin/qelfparser_p.cpp234
-rw-r--r--src/corelib/plugin/qelfparser_p.h103
-rw-r--r--src/corelib/plugin/qfactoryloader.cpp8
-rw-r--r--src/corelib/plugin/qfactoryloader_p.h4
-rw-r--r--src/corelib/plugin/qlibrary.cpp94
-rw-r--r--src/corelib/plugin/qplugin.h13
-rw-r--r--src/corelib/plugin/qsystemlibrary.cpp136
-rw-r--r--src/corelib/plugin/qsystemlibrary_p.h106
-rw-r--r--src/corelib/statemachine/qstatemachine.cpp3
-rw-r--r--src/corelib/thread/qatomic.cpp12
-rw-r--r--src/corelib/thread/qthread_unix.cpp35
-rw-r--r--src/corelib/tools/qbitarray.h4
-rw-r--r--src/corelib/tools/qbytearray.cpp42
-rw-r--r--src/corelib/tools/qbytearray.h4
-rw-r--r--src/corelib/tools/qchar.cpp17
-rw-r--r--src/corelib/tools/qcontiguouscache.h4
-rw-r--r--src/corelib/tools/qcryptographichash.cpp2
-rw-r--r--src/corelib/tools/qeasingcurve.cpp40
-rw-r--r--src/corelib/tools/qelapsedtimer_unix.cpp129
-rw-r--r--src/corelib/tools/qhash.h9
-rw-r--r--src/corelib/tools/qlinkedlist.h9
-rw-r--r--src/corelib/tools/qlist.h17
-rw-r--r--src/corelib/tools/qmap.h9
-rw-r--r--src/corelib/tools/qregexp.cpp3
-rw-r--r--src/corelib/tools/qregexp.h4
-rw-r--r--src/corelib/tools/qset.h4
-rw-r--r--src/corelib/tools/qshareddata.h28
-rw-r--r--src/corelib/tools/qsharedpointer_impl.h7
-rw-r--r--src/corelib/tools/qsimd.cpp306
-rw-r--r--src/corelib/tools/qsimd_p.h8
-rw-r--r--src/corelib/tools/qstring.cpp250
-rw-r--r--src/corelib/tools/qstring.h12
-rw-r--r--src/corelib/tools/qstringmatcher.cpp1
-rw-r--r--src/corelib/tools/qunicodetables.cpp119
-rw-r--r--src/corelib/tools/qunicodetables_p.h28
-rw-r--r--src/corelib/tools/qvector.h36
79 files changed, 2587 insertions, 966 deletions
diff --git a/src/corelib/arch/arch.pri b/src/corelib/arch/arch.pri
index 57bc80a..971069f 100644
--- a/src/corelib/arch/arch.pri
+++ b/src/corelib/arch/arch.pri
@@ -21,7 +21,9 @@ vxworks:HEADERS += arch/qatomic_vxworks.h
arch/qatomic_generic.h \
arch/qatomic_powerpc.h \
arch/qatomic_arm.h \
+ arch/qatomic_armv5.h \
arch/qatomic_armv6.h \
+ arch/qatomic_armv7.h \
arch/qatomic_i386.h \
arch/qatomic_mips.h \
arch/qatomic_s390.h \
diff --git a/src/corelib/arch/armv6/arch.pri b/src/corelib/arch/armv6/arch.pri
deleted file mode 100644
index fd0cce1..0000000
--- a/src/corelib/arch/armv6/arch.pri
+++ /dev/null
@@ -1,3 +0,0 @@
-#
-# ARMv6
-#
diff --git a/src/corelib/arch/qatomic_arm.h b/src/corelib/arch/qatomic_arm.h
index 9df02a2..1c1c8a5 100644
--- a/src/corelib/arch/qatomic_arm.h
+++ b/src/corelib/arch/qatomic_arm.h
@@ -44,387 +44,32 @@
QT_BEGIN_HEADER
-QT_BEGIN_NAMESPACE
-
-#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE
-
-inline bool QBasicAtomicInt::isReferenceCountingNative()
-{ return false; }
-inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE
-
-inline bool QBasicAtomicInt::isTestAndSetNative()
-{ return false; }
-inline bool QBasicAtomicInt::isTestAndSetWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
-#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_WAIT_FREE
-
-inline bool QBasicAtomicInt::isFetchAndStoreNative()
-{ return true; }
-inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
-{ return true; }
-
-#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE
-
-inline bool QBasicAtomicInt::isFetchAndAddNative()
-{ return false; }
-inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
-{ return false; }
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
-#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
-{ return true; }
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
-{ return true; }
-
-#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
-{ return false; }
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
-{ return false; }
-
-#ifndef QT_NO_ARM_EABI
-
-// kernel places a restartable cmpxchg implementation at a fixed address
-extern "C" typedef int (qt_atomic_eabi_cmpxchg_int_t)(int oldval, int newval, volatile int *ptr);
-extern "C" typedef int (qt_atomic_eabi_cmpxchg_ptr_t)(void *oldval, void *newval, volatile void *ptr);
-#define qt_atomic_eabi_cmpxchg_int (*reinterpret_cast<qt_atomic_eabi_cmpxchg_int_t *>(0xffff0fc0))
-#define qt_atomic_eabi_cmpxchg_ptr (*reinterpret_cast<qt_atomic_eabi_cmpxchg_ptr_t *>(0xffff0fc0))
-
-#else
-
-extern Q_CORE_EXPORT char q_atomic_lock;
-Q_CORE_EXPORT void qt_atomic_yield(int *);
-
-#ifdef Q_CC_RVCT
-
-Q_CORE_EXPORT __asm char q_atomic_swp(volatile char *ptr, char newval);
-
-#else
-
-inline char q_atomic_swp(volatile char *ptr, char newval)
-{
- register char ret;
- asm volatile("swpb %0,%2,[%3]"
- : "=&r"(ret), "=m" (*ptr)
- : "r"(newval), "r"(ptr)
- : "cc", "memory");
- return ret;
-}
-
-#endif // Q_CC_RVCT
-
-#endif // QT_NO_ARM_EABI
-
-// Reference counting
-
-inline bool QBasicAtomicInt::ref()
-{
-#ifndef QT_NO_ARM_EABI
- register int originalValue;
- register int newValue;
- do {
- originalValue = _q_value;
- newValue = originalValue + 1;
- } while (qt_atomic_eabi_cmpxchg_int(originalValue, newValue, &_q_value) != 0);
- return newValue != 0;
-#else
- int count = 0;
- while (q_atomic_swp(&q_atomic_lock, ~0) != 0)
- qt_atomic_yield(&count);
- int originalValue = _q_value++;
- q_atomic_swp(&q_atomic_lock, 0);
- return originalValue != -1;
-#endif
-}
-
-inline bool QBasicAtomicInt::deref()
-{
-#ifndef QT_NO_ARM_EABI
- register int originalValue;
- register int newValue;
- do {
- originalValue = _q_value;
- newValue = originalValue - 1;
- } while (qt_atomic_eabi_cmpxchg_int(originalValue, newValue, &_q_value) != 0);
- return newValue != 0;
-#else
- int count = 0;
- while (q_atomic_swp(&q_atomic_lock, ~0) != 0)
- qt_atomic_yield(&count);
- int originalValue = _q_value--;
- q_atomic_swp(&q_atomic_lock, 0);
- return originalValue != 1;
-#endif
-}
-
-// Test and set for integers
-
-inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
-{
-#ifndef QT_NO_ARM_EABI
- register int originalValue;
- do {
- originalValue = _q_value;
- if (originalValue != expectedValue)
- return false;
- } while (qt_atomic_eabi_cmpxchg_int(expectedValue, newValue, &_q_value) != 0);
- return true;
-#else
- bool returnValue = false;
- int count = 0;
- while (q_atomic_swp(&q_atomic_lock, ~0) != 0)
- qt_atomic_yield(&count);
- if (_q_value == expectedValue) {
- _q_value = newValue;
- returnValue = true;
- }
- q_atomic_swp(&q_atomic_lock, 0);
- return returnValue;
-#endif
-}
-
-inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
-{
- return testAndSetOrdered(expectedValue, newValue);
-}
-
-inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
-{
- return testAndSetOrdered(expectedValue, newValue);
-}
-
-inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
-{
- return testAndSetOrdered(expectedValue, newValue);
-}
-
-// Fetch and store for integers
-
-#ifndef Q_CC_RVCT
-
-inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
-{
- int originalValue;
- asm volatile("swp %0,%2,[%3]"
- : "=&r"(originalValue), "=m" (_q_value)
- : "r"(newValue), "r"(&_q_value)
- : "cc", "memory");
- return originalValue;
-}
-
-#endif
-
-inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
-{
- return fetchAndStoreOrdered(newValue);
-}
-
-inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
-{
- return fetchAndStoreOrdered(newValue);
-}
-
-inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
-{
- return fetchAndStoreOrdered(newValue);
-}
-
-// Fetch and add for integers
-
-inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
-{
-#ifndef QT_NO_ARM_EABI
- register int originalValue;
- register int newValue;
- do {
- originalValue = _q_value;
- newValue = originalValue + valueToAdd;
- } while (qt_atomic_eabi_cmpxchg_int(originalValue, newValue, &_q_value) != 0);
- return originalValue;
-#else
- int count = 0;
- while (q_atomic_swp(&q_atomic_lock, ~0) != 0)
- qt_atomic_yield(&count);
- int originalValue = _q_value;
- _q_value += valueToAdd;
- q_atomic_swp(&q_atomic_lock, 0);
- return originalValue;
-#endif
-}
-
-inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-// Test and set for pointers
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
-{
-#ifndef QT_NO_ARM_EABI
- register T *originalValue;
- do {
- originalValue = _q_value;
- if (originalValue != expectedValue)
- return false;
- } while (qt_atomic_eabi_cmpxchg_ptr(expectedValue, newValue, &_q_value) != 0);
- return true;
+#if defined(__ARM_ARCH_7__) \
+ || defined(__ARM_ARCH_7A__) \
+ || defined(__ARM_ARCH_7R__) \
+ || defined(__ARM_ARCH_7M__)
+# define QT_ARCH_ARMV7
+QT_BEGIN_INCLUDE_HEADER
+# include "QtCore/qatomic_armv7.h"
+QT_END_INCLUDE_HEADER
+#elif defined(__ARM_ARCH_6__) \
+ || defined(__ARM_ARCH_6J__) \
+ || defined(__ARM_ARCH_6T2__) \
+ || defined(__ARM_ARCH_6Z__) \
+ || defined(__ARM_ARCH_6K__) \
+ || defined(__ARM_ARCH_6ZK__) \
+ || defined(__ARM_ARCH_6M__) \
+ || (__TARGET_ARCH_ARM-0 >= 6)
+# define QT_ARCH_ARMV6
+QT_BEGIN_INCLUDE_HEADER
+# include "QtCore/qatomic_armv6.h"
+QT_END_INCLUDE_HEADER
#else
- bool returnValue = false;
- int count = 0;
- while (q_atomic_swp(&q_atomic_lock, ~0) != 0)
- qt_atomic_yield(&count);
- if (_q_value == expectedValue) {
- _q_value = newValue;
- returnValue = true;
- }
- q_atomic_swp(&q_atomic_lock, 0);
- return returnValue;
+# define QT_ARCH_ARMV5
+QT_BEGIN_INCLUDE_HEADER
+# include "QtCore/qatomic_armv5.h"
+QT_END_INCLUDE_HEADER
#endif
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
-{
- return testAndSetOrdered(expectedValue, newValue);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
-{
- return testAndSetOrdered(expectedValue, newValue);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
-{
- return testAndSetOrdered(expectedValue, newValue);
-}
-
-// Fetch and store for pointers
-
-#ifdef Q_CC_RVCT
-
-template <typename T>
-__asm T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
-{
- add r2, pc, #0
- bx r2
- arm
- swp r2,r1,[r0]
- mov r0, r2
- bx lr
- thumb
-}
-
-#else
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
-{
- T *originalValue;
- asm volatile("swp %0,%2,[%3]"
- : "=&r"(originalValue), "=m" (_q_value)
- : "r"(newValue), "r"(&_q_value)
- : "cc", "memory");
- return originalValue;
-}
-
-#endif // Q_CC_RVCT
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
-{
- return fetchAndStoreOrdered(newValue);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
-{
- return fetchAndStoreOrdered(newValue);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
-{
- return fetchAndStoreOrdered(newValue);
-}
-
-// Fetch and add for pointers
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
-{
-#ifndef QT_NO_ARM_EABI
- register T *originalValue;
- register T *newValue;
- do {
- originalValue = _q_value;
- newValue = originalValue + valueToAdd;
- } while (qt_atomic_eabi_cmpxchg_ptr(originalValue, newValue, &_q_value) != 0);
- return originalValue;
-#else
- int count = 0;
- while (q_atomic_swp(&q_atomic_lock, ~0) != 0)
- qt_atomic_yield(&count);
- T *originalValue = (_q_value);
- _q_value += valueToAdd;
- q_atomic_swp(&q_atomic_lock, 0);
- return originalValue;
-#endif
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/corelib/arch/qatomic_armv5.h b/src/corelib/arch/qatomic_armv5.h
new file mode 100644
index 0000000..ab48380
--- /dev/null
+++ b/src/corelib/arch/qatomic_armv5.h
@@ -0,0 +1,431 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** 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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_ARMV5_H
+#define QATOMIC_ARMV5_H
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isReferenceCountingNative()
+{ return false; }
+inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isTestAndSetNative()
+{ return false; }
+inline bool QBasicAtomicInt::isTestAndSetWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_WAIT_FREE
+
+inline bool QBasicAtomicInt::isFetchAndStoreNative()
+{ return true; }
+inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isFetchAndAddNative()
+{ return false; }
+inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
+{ return false; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
+{ return false; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
+{ return false; }
+
+#ifndef QT_NO_ARM_EABI
+
+// kernel places a restartable cmpxchg implementation at a fixed address
+extern "C" typedef int (qt_atomic_eabi_cmpxchg_int_t)(int oldval, int newval, volatile int *ptr);
+extern "C" typedef int (qt_atomic_eabi_cmpxchg_ptr_t)(void *oldval, void *newval, volatile void *ptr);
+#define qt_atomic_eabi_cmpxchg_int (*reinterpret_cast<qt_atomic_eabi_cmpxchg_int_t *>(0xffff0fc0))
+#define qt_atomic_eabi_cmpxchg_ptr (*reinterpret_cast<qt_atomic_eabi_cmpxchg_ptr_t *>(0xffff0fc0))
+
+#else
+
+extern Q_CORE_EXPORT char q_atomic_lock;
+Q_CORE_EXPORT void qt_atomic_yield(int *);
+
+#ifdef Q_CC_RVCT
+
+Q_CORE_EXPORT __asm char q_atomic_swp(volatile char *ptr, char newval);
+
+#else
+
+inline char q_atomic_swp(volatile char *ptr, char newval)
+{
+ register char ret;
+ asm volatile("swpb %0,%2,[%3]"
+ : "=&r"(ret), "=m" (*ptr)
+ : "r"(newval), "r"(ptr)
+ : "cc", "memory");
+ return ret;
+}
+
+#endif // Q_CC_RVCT
+
+#endif // QT_NO_ARM_EABI
+
+// Reference counting
+
+inline bool QBasicAtomicInt::ref()
+{
+#ifndef QT_NO_ARM_EABI
+ register int originalValue;
+ register int newValue;
+ do {
+ originalValue = _q_value;
+ newValue = originalValue + 1;
+ } while (qt_atomic_eabi_cmpxchg_int(originalValue, newValue, &_q_value) != 0);
+ return newValue != 0;
+#else
+ int count = 0;
+ while (q_atomic_swp(&q_atomic_lock, ~0) != 0)
+ qt_atomic_yield(&count);
+ int originalValue = _q_value++;
+ q_atomic_swp(&q_atomic_lock, 0);
+ return originalValue != -1;
+#endif
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+#ifndef QT_NO_ARM_EABI
+ register int originalValue;
+ register int newValue;
+ do {
+ originalValue = _q_value;
+ newValue = originalValue - 1;
+ } while (qt_atomic_eabi_cmpxchg_int(originalValue, newValue, &_q_value) != 0);
+ return newValue != 0;
+#else
+ int count = 0;
+ while (q_atomic_swp(&q_atomic_lock, ~0) != 0)
+ qt_atomic_yield(&count);
+ int originalValue = _q_value--;
+ q_atomic_swp(&q_atomic_lock, 0);
+ return originalValue != 1;
+#endif
+}
+
+// Test and set for integers
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+#ifndef QT_NO_ARM_EABI
+ register int originalValue;
+ do {
+ originalValue = _q_value;
+ if (originalValue != expectedValue)
+ return false;
+ } while (qt_atomic_eabi_cmpxchg_int(expectedValue, newValue, &_q_value) != 0);
+ return true;
+#else
+ bool returnValue = false;
+ int count = 0;
+ while (q_atomic_swp(&q_atomic_lock, ~0) != 0)
+ qt_atomic_yield(&count);
+ if (_q_value == expectedValue) {
+ _q_value = newValue;
+ returnValue = true;
+ }
+ q_atomic_swp(&q_atomic_lock, 0);
+ return returnValue;
+#endif
+}
+
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+// Fetch and store for integers
+
+#ifndef Q_CC_RVCT
+
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+{
+ int originalValue;
+ asm volatile("swp %0,%2,[%3]"
+ : "=&r"(originalValue), "=m" (_q_value)
+ : "r"(newValue), "r"(&_q_value)
+ : "cc", "memory");
+ return originalValue;
+}
+
+#endif
+
+inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+// Fetch and add for integers
+
+inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
+{
+#ifndef QT_NO_ARM_EABI
+ register int originalValue;
+ register int newValue;
+ do {
+ originalValue = _q_value;
+ newValue = originalValue + valueToAdd;
+ } while (qt_atomic_eabi_cmpxchg_int(originalValue, newValue, &_q_value) != 0);
+ return originalValue;
+#else
+ int count = 0;
+ while (q_atomic_swp(&q_atomic_lock, ~0) != 0)
+ qt_atomic_yield(&count);
+ int originalValue = _q_value;
+ _q_value += valueToAdd;
+ q_atomic_swp(&q_atomic_lock, 0);
+ return originalValue;
+#endif
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+// Test and set for pointers
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
+{
+#ifndef QT_NO_ARM_EABI
+ register T *originalValue;
+ do {
+ originalValue = _q_value;
+ if (originalValue != expectedValue)
+ return false;
+ } while (qt_atomic_eabi_cmpxchg_ptr(expectedValue, newValue, &_q_value) != 0);
+ return true;
+#else
+ bool returnValue = false;
+ int count = 0;
+ while (q_atomic_swp(&q_atomic_lock, ~0) != 0)
+ qt_atomic_yield(&count);
+ if (_q_value == expectedValue) {
+ _q_value = newValue;
+ returnValue = true;
+ }
+ q_atomic_swp(&q_atomic_lock, 0);
+ return returnValue;
+#endif
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+// Fetch and store for pointers
+
+#ifdef Q_CC_RVCT
+
+template <typename T>
+__asm T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+{
+ add r2, pc, #0
+ bx r2
+ arm
+ swp r2,r1,[r0]
+ mov r0, r2
+ bx lr
+ thumb
+}
+
+#else
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+{
+ T *originalValue;
+ asm volatile("swp %0,%2,[%3]"
+ : "=&r"(originalValue), "=m" (_q_value)
+ : "r"(newValue), "r"(&_q_value)
+ : "cc", "memory");
+ return originalValue;
+}
+
+#endif // Q_CC_RVCT
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+// Fetch and add for pointers
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+{
+#ifndef QT_NO_ARM_EABI
+ register T *originalValue;
+ register T *newValue;
+ do {
+ originalValue = _q_value;
+ newValue = originalValue + valueToAdd;
+ } while (qt_atomic_eabi_cmpxchg_ptr(originalValue, newValue, &_q_value) != 0);
+ return originalValue;
+#else
+ int count = 0;
+ while (q_atomic_swp(&q_atomic_lock, ~0) != 0)
+ qt_atomic_yield(&count);
+ T *originalValue = (_q_value);
+ _q_value += valueToAdd;
+ q_atomic_swp(&q_atomic_lock, 0);
+ return originalValue;
+#endif
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QATOMIC_ARMV5_H
diff --git a/src/corelib/arch/qatomic_armv6.h b/src/corelib/arch/qatomic_armv6.h
index 38b7069..1aa3b88 100644
--- a/src/corelib/arch/qatomic_armv6.h
+++ b/src/corelib/arch/qatomic_armv6.h
@@ -45,6 +45,7 @@
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
+
#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
inline bool QBasicAtomicInt::isReferenceCountingNative()
@@ -102,6 +103,13 @@ Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
#ifndef Q_CC_RVCT
+#ifndef Q_DATA_MEMORY_BARRIER
+# define Q_DATA_MEMORY_BARRIER asm volatile("":::"memory")
+#endif
+#ifndef Q_COMPILER_MEMORY_BARRIER
+# define Q_COMPILER_MEMORY_BARRIER asm volatile("":::"memory")
+#endif
+
inline bool QBasicAtomicInt::ref()
{
register int newValue;
@@ -138,7 +146,7 @@ inline bool QBasicAtomicInt::deref()
return newValue != 0;
}
-inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
{
register int result;
asm volatile("0:\n"
@@ -152,11 +160,11 @@ inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
: [expectedValue] "r" (expectedValue),
[newValue] "r" (newValue),
[_q_value] "r" (&_q_value)
- : "cc", "memory");
+ : "cc");
return result == 0;
}
-inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
{
register int originalValue;
register int result;
@@ -170,11 +178,11 @@ inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
"+m" (_q_value)
: [newValue] "r" (newValue),
[_q_value] "r" (&_q_value)
- : "cc", "memory");
+ : "cc");
return originalValue;
}
-inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
{
register int originalValue;
register int newValue;
@@ -191,12 +199,12 @@ inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
"+m" (_q_value)
: [valueToAdd] "r" (valueToAdd),
[_q_value] "r" (&_q_value)
- : "cc", "memory");
+ : "cc");
return originalValue;
}
template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
{
register T *result;
asm volatile("0:\n"
@@ -210,12 +218,12 @@ Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValu
: [expectedValue] "r" (expectedValue),
[newValue] "r" (newValue),
[_q_value] "r" (&_q_value)
- : "cc", "memory");
+ : "cc");
return result == 0;
}
template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
{
register T *originalValue;
register int result;
@@ -229,12 +237,12 @@ Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
"+m" (_q_value)
: [newValue] "r" (newValue),
[_q_value] "r" (&_q_value)
- : "cc", "memory");
+ : "cc");
return originalValue;
}
template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
{
register T *originalValue;
register T *newValue;
@@ -251,7 +259,7 @@ Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueTo
"+m" (_q_value)
: [valueToAdd] "r" (valueToAdd * sizeof(T)),
[_q_value] "r" (&_q_value)
- : "cc", "memory");
+ : "cc");
return originalValue;
}
@@ -263,9 +271,18 @@ Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueTo
// RVCT embedded assembly documentation:
// http://www.keil.com/support/man/docs/armcc/armcc_chddbeib.htm
-// save our pragma state and switch to ARM mode
-#pragma push
-#pragma arm
+#if __TARGET_ARCH_THUMB-0 < 4
+// save our pragma state and switch to ARM mode (unless using Thumb2)
+# pragma push
+# pragma arm
+#endif
+
+#ifndef Q_DATA_MEMORY_BARRIER
+# define Q_DATA_MEMORY_BARRIER __schedule_barrier()
+#endif
+#ifndef Q_COMPILER_MEMORY_BARRIER
+# define Q_COMPILER_MEMORY_BARRIER __schedule_barrier()
+#endif
inline bool QBasicAtomicInt::ref()
{
@@ -297,7 +314,7 @@ inline bool QBasicAtomicInt::deref()
return newValue != 0;
}
-inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
{
register int result;
retry:
@@ -311,7 +328,7 @@ inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
return result == 0;
}
-inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
{
register int originalValue;
register int result;
@@ -325,7 +342,7 @@ inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
return originalValue;
}
-inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
{
register int originalValue;
register int newValue;
@@ -342,7 +359,7 @@ inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
}
template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
{
register T *result;
retry:
@@ -357,7 +374,7 @@ Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValu
}
template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
{
register T *originalValue;
register int result;
@@ -372,7 +389,7 @@ Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
}
template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
{
register T *originalValue;
register T *newValue;
@@ -388,111 +405,153 @@ Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueTo
return originalValue;
}
-// go back to the previous pragma state (probably Thumb mode)
-#pragma pop
+#if __TARGET_ARCH_THUMB-0 < 4
+# pragma pop
#endif
-// common code
+#endif
-inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
-{
- return testAndSetOrdered(expectedValue, newValue);
-}
+// common code
inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
{
- return testAndSetOrdered(expectedValue, newValue);
+ bool returnValue = testAndSetRelaxed(expectedValue, newValue);
+ Q_DATA_MEMORY_BARRIER;
+ return returnValue;
}
inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
{
- return testAndSetOrdered(expectedValue, newValue);
+ Q_DATA_MEMORY_BARRIER;
+ return testAndSetRelaxed(expectedValue, newValue);
}
-inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
{
- return fetchAndStoreOrdered(newValue);
+ Q_DATA_MEMORY_BARRIER;
+ bool returnValue = testAndSetRelaxed(expectedValue, newValue);
+ Q_COMPILER_MEMORY_BARRIER;
+ return returnValue;
}
inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
{
- return fetchAndStoreOrdered(newValue);
+ int returnValue = fetchAndStoreRelaxed(newValue);
+ Q_DATA_MEMORY_BARRIER;
+ return returnValue;
}
inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
{
- return fetchAndStoreOrdered(newValue);
+ Q_DATA_MEMORY_BARRIER;
+ return fetchAndStoreRelaxed(newValue);
}
-inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
{
- return fetchAndAddOrdered(valueToAdd);
+ Q_DATA_MEMORY_BARRIER;
+ int returnValue = fetchAndStoreRelaxed(newValue);
+ Q_COMPILER_MEMORY_BARRIER;
+ return returnValue;
}
+
inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
{
- return fetchAndAddOrdered(valueToAdd);
+ int returnValue = fetchAndAddRelaxed(valueToAdd);
+ Q_DATA_MEMORY_BARRIER;
+ return returnValue;
}
inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
{
- return fetchAndAddOrdered(valueToAdd);
+ Q_DATA_MEMORY_BARRIER;
+ return fetchAndAddRelaxed(valueToAdd);
}
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
+inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
{
- return testAndSetOrdered(expectedValue, newValue);
+ Q_DATA_MEMORY_BARRIER;
+ int returnValue = fetchAndAddRelaxed(valueToAdd);
+ Q_COMPILER_MEMORY_BARRIER;
+ return returnValue;
}
template <typename T>
Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
{
- return testAndSetOrdered(expectedValue, newValue);
+ bool returnValue = testAndSetRelaxed(expectedValue, newValue);
+ Q_DATA_MEMORY_BARRIER;
+ return returnValue;
}
template <typename T>
Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
{
- return testAndSetOrdered(expectedValue, newValue);
+ Q_DATA_MEMORY_BARRIER;
+ return testAndSetRelaxed(expectedValue, newValue);
}
template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
{
- return fetchAndStoreOrdered(newValue);
+ Q_DATA_MEMORY_BARRIER;
+ bool returnValue = testAndSetAcquire(expectedValue, newValue);
+ Q_COMPILER_MEMORY_BARRIER;
+ return returnValue;
}
template <typename T>
Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
{
- return fetchAndStoreOrdered(newValue);
+ T *returnValue = fetchAndStoreRelaxed(newValue);
+ Q_DATA_MEMORY_BARRIER;
+ return returnValue;
}
template <typename T>
Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
{
- return fetchAndStoreOrdered(newValue);
+ Q_DATA_MEMORY_BARRIER;
+ return fetchAndStoreRelaxed(newValue);
}
template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
{
- return fetchAndAddOrdered(valueToAdd);
+ Q_DATA_MEMORY_BARRIER;
+ T *returnValue = fetchAndStoreRelaxed(newValue);
+ Q_COMPILER_MEMORY_BARRIER;
+ return returnValue;
}
template <typename T>
Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
{
- return fetchAndAddOrdered(valueToAdd);
+ T *returnValue = fetchAndAddRelaxed(valueToAdd);
+ Q_DATA_MEMORY_BARRIER;
+ return returnValue;
}
template <typename T>
Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
{
- return fetchAndAddOrdered(valueToAdd);
+ Q_DATA_MEMORY_BARRIER;
+ return fetchAndAddRelaxed(valueToAdd);
}
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+{
+ Q_DATA_MEMORY_BARRIER;
+ T *returnValue = fetchAndAddRelaxed(valueToAdd);
+ Q_COMPILER_MEMORY_BARRIER;
+ return returnValue;
+}
+
+#undef Q_DATA_MEMORY_BARRIER
+#undef Q_COMPILER_MEMORY_BARRIER
+
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/corelib/arch/qatomic_armv7.h b/src/corelib/arch/qatomic_armv7.h
new file mode 100644
index 0000000..a95c4ea
--- /dev/null
+++ b/src/corelib/arch/qatomic_armv7.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** 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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_ARMV7_H
+#define QATOMIC_ARMV7_H
+
+QT_BEGIN_HEADER
+
+// use the DMB instruction when compiling for ARMv7, ...
+#ifndef Q_CC_RCVT
+# define Q_DATA_MEMORY_BARRIER asm volatile("dmb\n":::"memory")
+#else
+# define Q_DATA_MEMORY_BARRIER do{__asm { dmb } __schedule_barrier();}while(0)
+#endif
+
+// ... but the implementation is otherwise identical to that for ARMv6
+QT_BEGIN_INCLUDE_HEADER
+#include "QtCore/qatomic_armv6.h"
+QT_END_INCLUDE_HEADER
+
+QT_END_HEADER
+
+#endif // QATOMIC_ARMV7_H
diff --git a/src/corelib/arch/symbian/arch.pri b/src/corelib/arch/symbian/arch.pri
index 3ef1c9e..84a4984 100644
--- a/src/corelib/arch/symbian/arch.pri
+++ b/src/corelib/arch/symbian/arch.pri
@@ -2,4 +2,4 @@
# Symbian architecture
#
SOURCES += $$QT_ARCH_CPP/qatomic_symbian.cpp \
- $$QT_ARCH_CPP/../armv6/qatomic_generic_armv6.cpp
+ $$QT_ARCH_CPP/qatomic_generic_armv6.cpp
diff --git a/src/corelib/arch/armv6/qatomic_generic_armv6.cpp b/src/corelib/arch/symbian/qatomic_generic_armv6.cpp
index 39d966a..39d966a 100644
--- a/src/corelib/arch/armv6/qatomic_generic_armv6.cpp
+++ b/src/corelib/arch/symbian/qatomic_generic_armv6.cpp
diff --git a/src/corelib/codecs/qtextcodec_symbian.cpp b/src/corelib/codecs/qtextcodec_symbian.cpp
index e4db9d7..9d7e856 100644
--- a/src/corelib/codecs/qtextcodec_symbian.cpp
+++ b/src/corelib/codecs/qtextcodec_symbian.cpp
@@ -53,12 +53,14 @@ struct QSymbianCodecInitData {
const char *aliases;
};
-/* This table contains the known Symbian codecs aliases. It is ordered by charsetId.
- It is required as symbian does not provide have aliases.
+/* This table contains the known Symbian codecs aliases.
+ It is required because symbian does not provide aliases for codecs.
+ It is also faster to have a name here than asking the system.
+ It is ordered by charsetId to allow binary search lookup
*/
static const QSymbianCodecInitData codecsData[] = {
- { /*268439485*/ KCharacterSetIdentifierShiftJis, 17, "Shift_JIS\0MS_Kanji\0csShiftJIS\0MS_KANJI\0SJIS\0" },
- { /*268439486*/ KCharacterSetIdentifierGb2312, 57, "GB2312\0csGB2312\0CN-GB\0EUC-CN\0" },
+ { /*268439485*/ KCharacterSetIdentifierShiftJis, 17, "Shift_JIS\0MS_Kanji\0csShiftJIS\0SJIS\0" },
+ { /*268439486*/ KCharacterSetIdentifierGb2312, 57, "GB2312\0csGB2312\0CN-GB\0EUC-CN\0" }, // Note: ConvertCharacterSetIdentifierToMibEnumL returns Mib 0 instaead of 57
{ /*268439487*/ KCharacterSetIdentifierBig5, 2026, "Big5\0csBig5\0Big5-ETen\0CP950\0BIG-FIVE\0CN-BIG5\0" },
{ /*268440246*/ KCharacterSetIdentifierCodePage1252, 2252, "windows-1252\0Code Page 1252\0CP1252\0MS-ANSI\0" },
// { /*268450576*/ KCharacterSetIdentifierIso88591, 4, "ISO-8859-1\0ISO_8859-1:1987\0iso-ir-100\0ISO_8859-1\0latin1\0l1\0IBM819\0CP819\0csISOLatin1\0ISO-IR-100\0ISO8859-1\0L1\0LATIN1\0CSISOLATIN1\0" },
@@ -108,15 +110,20 @@ static const QSymbianCodecInitData codecsData[] = {
{ /*270562232*/ 270562232, 2258, "Windows-1258\0CP1258\0WINDOWS-1258\0" },
{ /*270586888*/ 270586888, 0, "J5\0" },
{ /*271011982*/ 271011982, 0, "ISCII\0" },
- { /*271066541*/ 271066541, 2009, "CP850\0IBM850\0""850\0csPC850Multilingual\0" },
+ { /*271066541*/ 271066541, 2009, "CP850\0IBM850\0""850\0csPC850Multilingual\0" }, // Note: ConvertCharacterSetIdentifierToMibEnumL returns Mib 0 instead of 2009
{ /*271082493*/ 271082493, 0, "EXTENDED_SMS_7BIT\0" },
{ /*271082494*/ 271082494, 0, "gsm7_turkish_single\0" },
{ /*271082495*/ 271082495, 0, "turkish_locking_gsm7ext\0" },
{ /*271082496*/ 271082496, 0, "turkish_locking_single\0" },
+ { /*271082503*/ 271082503, 0, "portuguese_gsm7_single\0" },
+ { /*271082504*/ 271082504, 0, "portuguese_locking_gsm7ext\0" },
+ { /*271082505*/ 271082505, 0, "portuguese_locking_single\0" },
+ { /*271082506*/ 271082506, 0, "spanish_gsm7_single\0" },
+ { /*271085624*/ 271085624, 114, "GB18030\0" },
{ /*536929574*/ 536929574, 38, "EUC-KR\0" },
{ /*536936703*/ 536936703, 0, "CP949\0" },
- { /*536936705*/ 536936705, 37, "ISO-2022-KR\0" },
- { /*536941517*/ 536941517, 36, "KS_C_5601-1987\0" }
+ { /*536936705*/ 536936705, 37, "ISO-2022-KR\0csISO2022KR\0" },
+ { /*536941517*/ 536941517, 36, "KS_C_5601-1987\0iso-ir-149\0KS_C_5601-1989\0KSC_5601\0Korean\0csKSC56011987\0" }
};
@@ -657,6 +664,10 @@ QSymbianTextCodec *QSymbianTextCodec::init()
if (charsetId == localeMapperId)
localeMapper = c;
} else {
+ // We did not find the charsetId in our codecsData[], therefore we ask
+ // the OS for the codec name. We first try to get a "standard name" and fall
+ // back to array->At(i).Name(), if really needed. array->At(i).Name() is not
+ // guaranteed to be a correct name for QTextCodec::codecFromName().
QScopedPointer<HBufC8> buf;
QT_TRAP_THROWING(buf.reset(converter->ConvertCharacterSetIdentifierToStandardNameL(charsetId, qt_s60GetRFs())))
QByteArray name;
diff --git a/src/corelib/concurrent/qfuturewatcher.cpp b/src/corelib/concurrent/qfuturewatcher.cpp
index d4573c6..21b0789 100644
--- a/src/corelib/concurrent/qfuturewatcher.cpp
+++ b/src/corelib/concurrent/qfuturewatcher.cpp
@@ -359,6 +359,15 @@ void QFutureWatcherBase::connectNotify(const char * signal)
Q_D(QFutureWatcherBase);
if (qstrcmp(signal, SIGNAL(resultReadyAt(int))) == 0)
d->resultAtConnected.ref();
+#ifndef QT_NO_DEBUG
+ if (qstrcmp(signal, SIGNAL(finished())) == 0) {
+ if (futureInterface().isRunning()) {
+ //connections should be established before calling stFuture to avoid race.
+ // (The future could finish before the connection is made.)
+ qWarning("QFutureWatcher::connect: connecting after calling setFuture() is likely to produce race");
+ }
+ }
+#endif
}
void QFutureWatcherBase::disconnectNotify(const char * signal)
diff --git a/src/corelib/concurrent/qtconcurrentrun.cpp b/src/corelib/concurrent/qtconcurrentrun.cpp
index 5a9c755..e80a204 100644
--- a/src/corelib/concurrent/qtconcurrentrun.cpp
+++ b/src/corelib/concurrent/qtconcurrentrun.cpp
@@ -99,7 +99,7 @@
functions; passing by pointer is useful for calling non-const member
functions that modify the instance.
- For example, calling QString::split() (a const member function) in a
+ For example, calling QByteArray::split() (a const member function) in a
separate thread is done like this:
\snippet doc/src/snippets/code/src_corelib_concurrent_qtconcurrentrun.cpp 4
diff --git a/src/corelib/concurrent/qthreadpool.cpp b/src/corelib/concurrent/qthreadpool.cpp
index f25a494..265de33 100644
--- a/src/corelib/concurrent/qthreadpool.cpp
+++ b/src/corelib/concurrent/qthreadpool.cpp
@@ -250,6 +250,7 @@ bool QThreadPoolPrivate::tooManyThreadsActive() const
void QThreadPoolPrivate::startThread(QRunnable *runnable)
{
QScopedPointer <QThreadPoolThread> thread(new QThreadPoolThread(this));
+ thread->setObjectName(QLatin1String("Thread (pooled)"));
allThreads.insert(thread.data());
++activeThreads;
diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri
index b916b4d..260ed59 100644
--- a/src/corelib/global/global.pri
+++ b/src/corelib/global/global.pri
@@ -19,7 +19,7 @@ INCLUDEPATH += $$QT_BUILD_TREE/src/corelib/global
# Only used on platforms with CONFIG += precompile_header
PRECOMPILED_HEADER = global/qt_pch.h
-linux*-g++*:!static {
+linux*:!static:!linux-armcc:!linux-gcce {
QMAKE_LFLAGS += -Wl,-e,qt_core_boilerplate
prog=$$quote(if (/program interpreter: (.*)]/) { print $1; })
DEFINES += ELF_INTERPRETER=\\\"$$system(readelf -l /bin/ls | perl -n -e \'$$prog\')\\\"
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index a59a74f..c992735 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -1828,6 +1828,7 @@ QSysInfo::S60Version QSysInfo::s60Version()
CDir* contents;
TInt err = fileFinder.FindWildByDir(qt_S60Filter, qt_S60SystemInstallDir, contents);
if (err == KErrNone) {
+ QScopedPointer<CDir> contentsDeleter(contents);
err = contents->Sort(EDescending|ESortByName);
if (err == KErrNone && contents->Count() > 0 && (*contents)[0].iName.Length() >= 12) {
TInt major = (*contents)[0].iName[9] - '0';
@@ -1850,7 +1851,6 @@ QSysInfo::S60Version QSysInfo::s60Version()
}
}
}
- delete contents;
}
# ifdef Q_CC_NOKIAX86
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index a8758cf..986b5c5 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -400,6 +400,19 @@ namespace QT_NAMESPACE {}
# undef QT_HAVE_3DNOW
# endif
+#if defined(Q_CC_MSVC) && _MSC_VER >= 1600
+# define Q_COMPILER_RVALUE_REFS
+# define Q_COMPILER_INITIALIZER_LISTS
+# define Q_COMPILER_AUTO_TYPE
+# define Q_COMPILER_LAMBDA
+//# define Q_COMPILER_VARIADIC_TEMPLATES
+//# define Q_COMPILER_CLASS_ENUM
+//# define Q_COMPILER_DEFAULT_DELETE_MEMBERS
+//# define Q_COMPILER_UNICODE_STRINGS
+//# define Q_COMPILER_EXTERN_TEMPLATES
+# endif
+
+
#elif defined(__BORLANDC__) || defined(__TURBOC__)
# define Q_CC_BOR
# define Q_INLINE_TEMPLATE
@@ -474,6 +487,26 @@ namespace QT_NAMESPACE {}
# define QT_NO_ARM_EABI
# endif
# endif
+# if defined(__GXX_EXPERIMENTAL_CXX0X__)
+# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 403
+ /* C++0x features supported in GCC 4.3: */
+# define Q_COMPILER_RVALUE_REFS
+# endif
+# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 404
+ /* C++0x features supported in GCC 4.4: */
+# define Q_COMPILER_VARIADIC_TEMPLATES
+# define Q_COMPILER_AUTO_TYPE
+# define Q_COMPILER_EXTERN_TEMPLATES
+# define Q_COMPILER_DEFAULT_DELETE_MEMBERS
+# define Q_COMPILER_CLASS_ENUM
+# define Q_COMPILER_INITIALIZER_LISTS
+# endif
+# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 405
+ /* C++0x features supported in GCC 4.5: */
+# define Q_COMPILER_LAMBDA
+# define Q_COMPILER_UNICODE_STRINGS
+# endif
+# endif
/* IBM compiler versions are a bit messy. There are actually two products:
the C product, and the C++ product. The C++ compiler is always packaged
@@ -1058,7 +1091,7 @@ redefine to built-in booleans to make autotests work properly */
typedef int QNoImplicitBoolCast;
-#if defined(QT_ARCH_ARM) || defined(QT_ARCH_ARMV6) || defined(QT_ARCH_AVR32) || (defined(QT_ARCH_MIPS) && (defined(Q_WS_QWS) || defined(Q_OS_WINCE))) || defined(QT_ARCH_SH) || defined(QT_ARCH_SH4A)
+#if defined(QT_ARCH_ARM) || defined(QT_ARCH_AVR32) || (defined(QT_ARCH_MIPS) && (defined(Q_WS_QWS) || defined(Q_OS_WINCE))) || defined(QT_ARCH_SH) || defined(QT_ARCH_SH4A)
#define QT_NO_FPU
#endif
@@ -2612,6 +2645,12 @@ QT_LICENSED_MODULE(DBus)
# define QT_NO_PROCESS
#endif
+#if defined (__ELF__)
+# if defined (Q_OS_LINUX) || defined (Q_OS_SOLARIS) || defined (Q_OS_FREEBSD) || defined (Q_OS_OPENBSD) || defined (Q_OS_IRIX)
+# define Q_OF_ELF
+# endif
+#endif
+
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
index ea7e2e4..d493390 100644
--- a/src/corelib/global/qlibraryinfo.cpp
+++ b/src/corelib/global/qlibraryinfo.cpp
@@ -66,6 +66,8 @@ QT_END_NAMESPACE
QT_BEGIN_NAMESPACE
+extern void qDumpCPUFeatures(); // in qsimd.cpp
+
#ifndef QT_NO_SETTINGS
struct QLibrarySettings
@@ -508,6 +510,17 @@ void qt_core_boilerplate()
"Contact: Nokia Corporation (qt-info@nokia.com)\n"
"\n"
"Build key: " QT_BUILD_KEY "\n"
+ "Compat build key: "
+#ifdef QT_BUILD_KEY_COMPAT
+ "| " QT_BUILD_KEY_COMPAT " "
+#endif
+#ifdef QT_BUILD_KEY_COMPAT2
+ "| " QT_BUILD_KEY_COMPAT2 " "
+#endif
+#ifdef QT_BUILD_KEY_COMPAT3
+ "| " QT_BUILD_KEY_COMPAT3 " "
+#endif
+ "|\n"
"Build date: %s\n"
"Installation prefix: %s\n"
"Library path: %s\n"
@@ -517,6 +530,8 @@ void qt_core_boilerplate()
qt_configure_libraries_path_str + 12,
qt_configure_headers_path_str + 12);
+ QT_PREPEND_NAMESPACE(qDumpCPUFeatures)();
+
#ifdef QT_EVAL
extern void qt_core_eval_init(uint);
qt_core_eval_init(1);
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index c66813a..a531009 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -92,6 +92,7 @@ Qt {
Q_ENUMS(ConnectionType)
#ifndef QT_NO_GESTURES
Q_ENUMS(GestureState)
+ Q_ENUMS(GestureType)
#endif
#endif // (defined(Q_MOC_RUN) || defined(QT_JAMBI_RUN))
diff --git a/src/corelib/global/qnumeric.cpp b/src/corelib/global/qnumeric.cpp
index 75fd31e..7ddb9e2 100644
--- a/src/corelib/global/qnumeric.cpp
+++ b/src/corelib/global/qnumeric.cpp
@@ -44,14 +44,49 @@
QT_BEGIN_NAMESPACE
+/*!
+ Returns true if the double \a {d} is equivalent to infinity.
+*/
Q_CORE_EXPORT bool qIsInf(double d) { return qt_is_inf(d); }
+
+/*!
+ Returns true if the double \a {d} is not a number (NaN).
+*/
Q_CORE_EXPORT bool qIsNaN(double d) { return qt_is_nan(d); }
+
+/*!
+ Returns true if the double \a {d} is a finite number.
+*/
Q_CORE_EXPORT bool qIsFinite(double d) { return qt_is_finite(d); }
+
+/*!
+ Returns true if the float \a {f} is equivalent to infinity.
+*/
Q_CORE_EXPORT bool qIsInf(float f) { return qt_is_inf(f); }
+
+/*!
+ Returns true if the float \a {f} is not a number (NaN).
+*/
Q_CORE_EXPORT bool qIsNaN(float f) { return qt_is_nan(f); }
+
+/*!
+ Returns true if the float \a {f} is a finite number.
+*/
Q_CORE_EXPORT bool qIsFinite(float f) { return qt_is_finite(f); }
+
+/*!
+ Returns the bit pattern of a signalling NaN as a double.
+*/
Q_CORE_EXPORT double qSNaN() { return qt_snan(); }
+
+/*!
+ Returns the bit pattern of a quiet NaN as a double.
+*/
Q_CORE_EXPORT double qQNaN() { return qt_qnan(); }
+
+/*!
+ Returns the bit pattern for an infinite number as a double.
+*/
Q_CORE_EXPORT double qInf() { return qt_inf(); }
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index c7cf87f..bbe9226 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -767,6 +767,7 @@ QString QDir::relativeFilePath(const QString &fileName) const
return result;
}
+#ifndef QT_NO_DEPRECATED
/*!
\obsolete
@@ -776,6 +777,7 @@ QString QDir::convertSeparators(const QString &pathName)
{
return toNativeSeparators(pathName);
}
+#endif
/*!
\since 4.2
diff --git a/src/corelib/io/qdir.h b/src/corelib/io/qdir.h
index 7e5fbac..9eab24f 100644
--- a/src/corelib/io/qdir.h
+++ b/src/corelib/io/qdir.h
@@ -128,6 +128,10 @@ public:
QDir &operator=(const QDir &);
QDir &operator=(const QString &path);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QDir &operator=(QDir &&other)
+ { qSwap(d_ptr, other.d_ptr); return *this; }
+#endif
void setPath(const QString &path);
QString path() const;
diff --git a/src/corelib/io/qfileinfo.h b/src/corelib/io/qfileinfo.h
index 92bea5e..3eff208 100644
--- a/src/corelib/io/qfileinfo.h
+++ b/src/corelib/io/qfileinfo.h
@@ -71,6 +71,10 @@ public:
~QFileInfo();
QFileInfo &operator=(const QFileInfo &fileinfo);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QFileInfo&operator=(QFileInfo &&other)
+ { qSwap(d_ptr, other.d_ptr); return *this; }
+#endif
bool operator==(const QFileInfo &fileinfo); // 5.0 - remove me
bool operator==(const QFileInfo &fileinfo) const;
inline bool operator!=(const QFileInfo &fileinfo) { return !(operator==(fileinfo)); } // 5.0 - remove me
diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp
index 1aba4a7..8fd0919 100644
--- a/src/corelib/io/qfilesystemengine_win.cpp
+++ b/src/corelib/io/qfilesystemengine_win.cpp
@@ -180,7 +180,7 @@ static void resolveLibs()
triedResolve = true;
#if !defined(Q_OS_WINCE)
- HINSTANCE advapiHnd = LoadLibrary(L"advapi32");
+ HINSTANCE advapiHnd = QSystemLibrary::load(L"advapi32");
if (advapiHnd) {
ptrGetNamedSecurityInfoW = (PtrGetNamedSecurityInfoW)GetProcAddress(advapiHnd, "GetNamedSecurityInfoW");
ptrLookupAccountSidW = (PtrLookupAccountSidW)GetProcAddress(advapiHnd, "LookupAccountSidW");
@@ -212,7 +212,7 @@ static void resolveLibs()
ptrFreeSid(pWorld);
}
}
- HINSTANCE userenvHnd = LoadLibrary(L"userenv");
+ HINSTANCE userenvHnd = QSystemLibrary::load(L"userenv");
if (userenvHnd)
ptrGetUserProfileDirectoryW = (PtrGetUserProfileDirectoryW)GetProcAddress(userenvHnd, "GetUserProfileDirectoryW");
HINSTANCE kernel32 = LoadLibrary(L"kernel32");
@@ -246,7 +246,7 @@ static bool resolveUNCLibs()
#endif
triedResolve = true;
#if !defined(Q_OS_WINCE)
- HINSTANCE hLib = LoadLibrary(L"netapi32");
+ HINSTANCE hLib = QSystemLibrary::load(L"Netapi32");
if (hLib) {
ptrNetShareEnum = (PtrNetShareEnum)GetProcAddress(hLib, "NetShareEnum");
if (ptrNetShareEnum)
diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp
index 26e587d..8544fba 100644
--- a/src/corelib/io/qiodevice.cpp
+++ b/src/corelib/io/qiodevice.cpp
@@ -1633,6 +1633,12 @@ QString QIODevice::errorString() const
This function is called by QIODevice. Reimplement this function
when creating a subclass of QIODevice.
+ When reimplementing this function it is important that this function
+ reads all the required data before returning. This is required in order
+ for QDataStream to be able to operate on the class. QDataStream assumes
+ all the requested information was read and therefore does not retry reading
+ if there was a problem.
+
\sa read() readLine() writeData()
*/
@@ -1645,6 +1651,12 @@ QString QIODevice::errorString() const
This function is called by QIODevice. Reimplement this function
when creating a subclass of QIODevice.
+ When reimplementing this function it is important that this function
+ writes all the data available before returning. This is required in order
+ for QDataStream to be able to operate on the class. QDataStream assumes
+ all the information was written and therefore does not retry writing if
+ there was a problem.
+
\sa read() write()
*/
diff --git a/src/corelib/io/qprocess_symbian.cpp b/src/corelib/io/qprocess_symbian.cpp
index af657b2..003e781 100644
--- a/src/corelib/io/qprocess_symbian.cpp
+++ b/src/corelib/io/qprocess_symbian.cpp
@@ -375,10 +375,9 @@ QProcessActive::QProcessActive()
// Nothing to do
}
-// Called from ProcessManagerThread
+// Called from main thread
QProcessActive::~QProcessActive()
{
- Cancel();
process = NULL;
pproc = NULL;
}
@@ -482,10 +481,9 @@ QProcessManagerMediator::QProcessManagerMediator()
// Nothing to do
}
-// Called from ProcessManagerThread
+// Called from main thread
QProcessManagerMediator::~QProcessManagerMediator()
{
- Cancel();
processManagerThread.Close();
currentCommand = ENoCommand;
currentObserver = NULL;
@@ -648,25 +646,36 @@ QProcessManager::QProcessManager()
QProcessManager::~QProcessManager()
{
QPROCESS_DEBUG_PRINT("QProcessManager::~QProcessManager()");
- // Cancel death listening for all child processes
- if (mediator) {
- QMap<int, QProcessActive *>::Iterator it = children.begin();
- while (it != children.end()) {
- // Remove all monitors
- QProcessActive *active = it.value();
- mediator->remove(active);
-
- QPROCESS_DEBUG_PRINT("QProcessManager::~QProcessManager() removed listening for a process");
- ++it;
+
+ // Check if manager thread is still alive. If this destructor is ran as part of global
+ // static cleanup, manager thread will most likely be terminated by kernel at this point,
+ // so trying to delete QProcessActives and QProcessMediators will panic as they
+ // will still be active. They can also no longer be canceled as the thread is already gone.
+ // In case manager thread has already died, we simply do nothing and let the deletion of
+ // the main heap at process exit take care of stray objects.
+
+ if (managerThread.Handle() && managerThread.ExitType() == EExitPending) {
+ // Cancel death listening for all child processes
+ if (mediator) {
+ QMap<int, QProcessActive *>::Iterator it = children.begin();
+ while (it != children.end()) {
+ // Remove all monitors
+ QProcessActive *active = it.value();
+ mediator->remove(active);
+
+ QPROCESS_DEBUG_PRINT("QProcessManager::~QProcessManager() removed listening for a process");
+ ++it;
+ }
+
+ // Terminate process manager thread.
+ mediator->terminate();
+ delete mediator;
}
- // Terminate process manager thread.
- mediator->terminate();
- delete mediator;
+ qDeleteAll(children.values());
+ children.clear();
}
- qDeleteAll(children.values());
- children.clear();
managerThread.Close();
managerMutex.Close();
}
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp
index 384804a..f25c272 100644
--- a/src/corelib/io/qsettings.cpp
+++ b/src/corelib/io/qsettings.cpp
@@ -69,7 +69,7 @@
#ifdef Q_OS_WIN // for homedirpath reading from registry
#include "qt_windows.h"
-#include "qlibrary.h"
+#include <private/qsystemlibrary_p.h>
#endif // Q_OS_WIN
#endif // QT_NO_QOBJECT
@@ -1044,9 +1044,9 @@ static QString windowsConfigPath(int type)
// We can't use QLibrary if there is QT_NO_QOBJECT is defined
// This only happens when bootstrapping qmake.
#ifndef Q_OS_WINCE
- QLibrary library(QLatin1String("shell32"));
+ QSystemLibrary library(QLatin1String("shell32"));
#else
- QLibrary library(QLatin1String("coredll"));
+ QSystemLibrary library(QLatin1String("coredll"));
#endif // Q_OS_WINCE
typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, LPWSTR, int, BOOL);
GetSpecialFolderPath SHGetSpecialFolderPath = (GetSpecialFolderPath)library.resolve("SHGetSpecialFolderPathW");
diff --git a/src/corelib/io/qsettings_win.cpp b/src/corelib/io/qsettings_win.cpp
index de96e06..b3fe734 100644
--- a/src/corelib/io/qsettings_win.cpp
+++ b/src/corelib/io/qsettings_win.cpp
@@ -535,6 +535,15 @@ bool QWinSettingsPrivate::readKey(HKEY parentHandle, const QString &rSubKey, QVa
break;
}
+ case REG_QWORD: {
+ Q_ASSERT(data.size() == sizeof(qint64));
+ qint64 i;
+ memcpy((char*)&i, data.constData(), sizeof(qint64));
+ if (value != 0)
+ *value = i;
+ break;
+ }
+
default:
qWarning("QSettings: Unknown data %d type in Windows registry", static_cast<int>(dataType));
if (value != 0)
@@ -683,10 +692,19 @@ void QWinSettingsPrivate::set(const QString &uKey, const QVariant &value)
break;
}
- case QVariant::Int: {
+ case QVariant::Int:
+ case QVariant::UInt: {
type = REG_DWORD;
- int i = value.toInt();
- regValueBuff = QByteArray((const char*)&i, sizeof(int));
+ qint32 i = value.toInt();
+ regValueBuff = QByteArray((const char*)&i, sizeof(qint32));
+ break;
+ }
+
+ case QVariant::LongLong:
+ case QVariant::ULongLong: {
+ type = REG_QWORD;
+ qint64 i = value.toLongLong();
+ regValueBuff = QByteArray((const char*)&i, sizeof(qint64));
break;
}
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index 20ec995..6452c0f 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -176,7 +176,6 @@
*/
#include "qplatformdefs.h"
#include "qurl.h"
-#include "private/qunicodetables_p.h"
#include "qatomic.h"
#include "qbytearray.h"
#include "qdir.h"
@@ -3446,23 +3445,26 @@ QString QUrlPrivate::canonicalHost() const
if (host.contains(QLatin1Char(':'))) {
// This is an IP Literal, use _IPLiteral to validate
QByteArray ba = host.toLatin1();
+ bool needsBraces = false;
if (!ba.startsWith('[')) {
// surround the IP Literal with [ ] if it's not already done so
ba.reserve(ba.length() + 2);
ba.prepend('[');
ba.append(']');
+ needsBraces = true;
}
const char *ptr = ba.constData();
if (!_IPLiteral(&ptr))
that->host.clear();
+ else if (needsBraces)
+ that->host = QString::fromLatin1(ba.toLower());
else
that->host = host.toLower();
} else {
that->host = qt_ACE_do(host, NormalizeAce);
- if (that->host.isNull())
- that->isHostValid = false;
}
+ that->isHostValid = !that->host.isNull();
return that->host;
}
@@ -3777,6 +3779,10 @@ void QUrlPrivate::validate() const
QString auth = authority(); // causes the non-encoded forms to be valid
+ // authority() calls canonicalHost() which sets this
+ if (!isHostValid)
+ return;
+
if (scheme == QLatin1String("mailto")) {
if (!host.isEmpty() || port != -1 || !userName.isEmpty() || !password.isEmpty()) {
that->isValid = false;
@@ -3950,9 +3956,10 @@ QByteArray QUrlPrivate::toEncoded(QUrl::FormattingOptions options) const
url += scheme.toLatin1();
url += ':';
}
+ QString savedHost = host; // pre-validation, may be invalid!
QString auth = authority();
bool doFileScheme = scheme == QLatin1String("file") && encodedPath.startsWith('/');
- if ((options & QUrl::RemoveAuthority) != QUrl::RemoveAuthority && (!auth.isEmpty() || doFileScheme)) {
+ if ((options & QUrl::RemoveAuthority) != QUrl::RemoveAuthority && (!auth.isEmpty() || doFileScheme || !savedHost.isEmpty())) {
if (doFileScheme && !encodedPath.startsWith('/'))
url += '/';
url += "//";
@@ -3978,6 +3985,12 @@ QByteArray QUrlPrivate::toEncoded(QUrl::FormattingOptions options) const
url += '[';
url += host.toLatin1();
url += ']';
+ } else if (host.isEmpty() && !savedHost.isEmpty()) {
+ // this case is only possible with an invalid URL
+ // it's here only so that we can keep the original, invalid hostname
+ // in encodedOriginal.
+ // QUrl::isValid() will return false, so toEncoded() can be anything (it's not valid)
+ url += savedHost.toUtf8();
} else {
url += QUrl::toAce(host);
}
@@ -4097,7 +4110,7 @@ const QByteArray &QUrlPrivate::normalized() const
QString QUrlPrivate::createErrorString()
{
- if (isValid)
+ if (isValid && isHostValid)
return QString();
QString errorString(QLatin1String(QT_TRANSLATE_NOOP(QUrl, "Invalid URL \"")));
@@ -4121,7 +4134,10 @@ QString QUrlPrivate::createErrorString()
errorString += QLatin1String(QT_TRANSLATE_NOOP(QUrl, "\'"));
} else {
errorString += QLatin1String(QT_TRANSLATE_NOOP(QUrl, ": "));
- errorString += QLatin1String(errorInfo._message);
+ if (isHostValid)
+ errorString += QLatin1String(errorInfo._message);
+ else
+ errorString += QLatin1String(QT_TRANSLATE_NOOP(QUrl, "invalid hostname"));
}
if (errorInfo._found) {
errorString += QLatin1String(QT_TRANSLATE_NOOP(QUrl, ", but found \'"));
@@ -4484,7 +4500,7 @@ void QUrl::setAuthority(const QString &authority)
if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
detach();
- QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized);
+ QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized | QUrlPrivate::HostCanonicalized);
d->setAuthority(authority);
}
@@ -5005,6 +5021,10 @@ void QUrl::setEncodedQuery(const QByteArray &query)
pairDelimiter(), and the key and value are delimited by
valueDelimiter().
+ \note This method does not encode spaces (ASCII 0x20) as plus (+) signs,
+ like HTML forms do. If you need that kind of encoding, you must encode
+ the value yourself and use QUrl::setEncodedQueryItems.
+
\sa setQueryDelimiters(), queryItems(), setEncodedQueryItems()
*/
void QUrl::setQueryItems(const QList<QPair<QString, QString> > &query)
@@ -5075,6 +5095,10 @@ void QUrl::setEncodedQueryItems(const QList<QPair<QByteArray, QByteArray> > &que
character returned by valueDelimiter(). Each key/value pair is
delimited by the character returned by pairDelimiter().
+ \note This method does not encode spaces (ASCII 0x20) as plus (+) signs,
+ like HTML forms do. If you need that kind of encoding, you must encode
+ the value yourself and use QUrl::addEncodedQueryItem.
+
\sa addEncodedQueryItem()
*/
void QUrl::addQueryItem(const QString &key, const QString &value)
@@ -5131,6 +5155,10 @@ void QUrl::addEncodedQueryItem(const QByteArray &key, const QByteArray &value)
/*!
Returns the query string of the URL, as a map of keys and values.
+ \note This method does not decode spaces plus (+) signs as spaces (ASCII
+ 0x20), like HTML forms do. If you need that kind of decoding, you must
+ use QUrl::encodedQueryItems and decode the data yourself.
+
\sa setQueryItems(), setEncodedQuery()
*/
QList<QPair<QString, QString> > QUrl::queryItems() const
@@ -5235,6 +5263,10 @@ bool QUrl::hasEncodedQueryItem(const QByteArray &key) const
Returns the first query string value whose key is equal to \a key
from the URL.
+ \note This method does not decode spaces plus (+) signs as spaces (ASCII
+ 0x20), like HTML forms do. If you need that kind of decoding, you must
+ use QUrl::encodedQueryItemValue and decode the data yourself.
+
\sa allQueryItemValues()
*/
QString QUrl::queryItemValue(const QString &key) const
@@ -5279,6 +5311,10 @@ QByteArray QUrl::encodedQueryItemValue(const QByteArray &key) const
Returns the a list of query string values whose key is equal to
\a key from the URL.
+ \note This method does not decode spaces plus (+) signs as spaces (ASCII
+ 0x20), like HTML forms do. If you need that kind of decoding, you must
+ use QUrl::allEncodedQueryItemValues and decode the data yourself.
+
\sa queryItemValue()
*/
QStringList QUrl::allQueryItemValues(const QString &key) const
@@ -5657,7 +5693,7 @@ QString QUrl::toString(FormattingOptions options) const
if ((options & QUrl::RemoveAuthority) != QUrl::RemoveAuthority) {
bool doFileScheme = d->scheme == QLatin1String("file") && ourPath.startsWith(QLatin1Char('/'));
QString tmp = d->authority(options);
- if (!tmp.isEmpty() || doFileScheme) {
+ if (!tmp.isNull() || doFileScheme) {
if (doFileScheme && !ourPath.startsWith(QLatin1Char('/')))
url += QLatin1Char('/');
url += QLatin1String("//");
diff --git a/src/corelib/io/qurl.h b/src/corelib/io/qurl.h
index 162aa7c..563be5f 100644
--- a/src/corelib/io/qurl.h
+++ b/src/corelib/io/qurl.h
@@ -94,6 +94,10 @@ public:
#ifndef QT_NO_URL_CAST_FROM_STRING
QUrl &operator =(const QString &url);
#endif
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QUrl &operator=(QUrl &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
~QUrl();
void setUrl(const QString &url);
diff --git a/src/corelib/kernel/qabstractitemmodel.cpp b/src/corelib/kernel/qabstractitemmodel.cpp
index 3a6395b..4fc9792 100644
--- a/src/corelib/kernel/qabstractitemmodel.cpp
+++ b/src/corelib/kernel/qabstractitemmodel.cpp
@@ -2603,9 +2603,13 @@ bool QAbstractItemModel::beginMoveRows(const QModelIndex &sourceParent, int sour
return false;
}
- d->changes.push(QAbstractItemModelPrivate::Change(sourceParent, sourceFirst, sourceLast));
+ QAbstractItemModelPrivate::Change sourceChange(sourceParent, sourceFirst, sourceLast);
+ sourceChange.needsAdjust = sourceParent.isValid() && sourceParent.row() >= destinationChild && sourceParent.parent() == destinationParent;
+ d->changes.push(sourceChange);
int destinationLast = destinationChild + (sourceLast - sourceFirst);
- d->changes.push(QAbstractItemModelPrivate::Change(destinationParent, destinationChild, destinationLast));
+ QAbstractItemModelPrivate::Change destinationChange(destinationParent, destinationChild, destinationLast);
+ destinationChange.needsAdjust = destinationParent.isValid() && destinationParent.row() >= sourceLast && destinationParent.parent() == sourceParent;
+ d->changes.push(destinationChange);
emit rowsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild);
emit layoutAboutToBeChanged();
@@ -2635,7 +2639,17 @@ void QAbstractItemModel::endMoveRows()
d->itemsMoved(removeChange.parent, removeChange.first, removeChange.last, insertChange.parent, insertChange.first, Qt::Vertical);
- emit rowsMoved(removeChange.parent, removeChange.first, removeChange.last, insertChange.parent, insertChange.first);
+ QModelIndex adjustedSource = removeChange.parent;
+ QModelIndex adjustedDestination = insertChange.parent;
+
+ const int numMoved = removeChange.last - removeChange.first + 1;
+ if (insertChange.needsAdjust)
+ adjustedDestination = createIndex(adjustedDestination.row() - numMoved, adjustedDestination.column(), adjustedDestination.internalPointer());
+
+ if (removeChange.needsAdjust)
+ adjustedSource = createIndex(adjustedSource.row() + numMoved, adjustedSource.column(), adjustedSource.internalPointer());
+
+ emit rowsMoved(adjustedSource, removeChange.first, removeChange.last, adjustedDestination, insertChange.first);
emit layoutChanged();
}
@@ -2812,9 +2826,13 @@ bool QAbstractItemModel::beginMoveColumns(const QModelIndex &sourceParent, int s
return false;
}
- d->changes.push(QAbstractItemModelPrivate::Change(sourceParent, sourceFirst, sourceLast));
+ QAbstractItemModelPrivate::Change sourceChange(sourceParent, sourceFirst, sourceLast);
+ sourceChange.needsAdjust = sourceParent.isValid() && sourceParent.row() >= destinationChild && sourceParent.parent() == destinationParent;
+ d->changes.push(sourceChange);
int destinationLast = destinationChild + (sourceLast - sourceFirst);
- d->changes.push(QAbstractItemModelPrivate::Change(destinationParent, destinationChild, destinationLast));
+ QAbstractItemModelPrivate::Change destinationChange(destinationParent, destinationChild, destinationLast);
+ destinationChange.needsAdjust = destinationParent.isValid() && destinationParent.row() >= sourceLast && destinationParent.parent() == sourceParent;
+ d->changes.push(destinationChange);
d->itemsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Horizontal);
@@ -2845,7 +2863,17 @@ void QAbstractItemModel::endMoveColumns()
d->itemsMoved(removeChange.parent, removeChange.first, removeChange.last, insertChange.parent, insertChange.first, Qt::Horizontal);
- emit columnsMoved(removeChange.parent, removeChange.first, removeChange.last, insertChange.parent, insertChange.first);
+ QModelIndex adjustedSource = removeChange.parent;
+ QModelIndex adjustedDestination = insertChange.parent;
+
+ const int numMoved = removeChange.last - removeChange.first + 1;
+ if (insertChange.needsAdjust)
+ adjustedDestination = createIndex(adjustedDestination.row(), adjustedDestination.column() - numMoved, adjustedDestination.internalPointer());
+
+ if (removeChange.needsAdjust)
+ adjustedSource = createIndex(adjustedSource.row(), adjustedSource.column() + numMoved, adjustedSource.internalPointer());
+
+ emit columnsMoved(adjustedSource, removeChange.first, removeChange.last, adjustedDestination, insertChange.first);
emit layoutChanged();
}
diff --git a/src/corelib/kernel/qabstractitemmodel_p.h b/src/corelib/kernel/qabstractitemmodel_p.h
index 7844a10..3113dff 100644
--- a/src/corelib/kernel/qabstractitemmodel_p.h
+++ b/src/corelib/kernel/qabstractitemmodel_p.h
@@ -133,11 +133,26 @@ public:
struct Change {
Change() : first(-1), last(-1) {}
- Change(const Change &c) : parent(c.parent), first(c.first), last(c.last) {}
- Change(const QModelIndex &p, int f, int l) : parent(p), first(f), last(l) {}
+ Change(const Change &c) : parent(c.parent), first(c.first), last(c.last), needsAdjust(c.needsAdjust) {}
+ Change(const QModelIndex &p, int f, int l) : parent(p), first(f), last(l), needsAdjust(false) {}
QModelIndex parent;
int first, last;
+
+ // In cases such as this:
+ // - A
+ // - B
+ // - C
+ // - - D
+ // - - E
+ // - - F
+ //
+ // If B is moved to above E, C is the source parent in the signal and its row is 2. When the move is
+ // completed however, C is at row 1 and there is no row 2 at the same level in the model at all.
+ // The QModelIndex is adjusted to correct that in those cases before reporting it though the
+ // rowsMoved signal.
+ bool needsAdjust;
+
bool isValid() { return first >= 0 && last >= 0; }
};
QStack<Change> changes;
diff --git a/src/corelib/kernel/qcore_symbian_p.cpp b/src/corelib/kernel/qcore_symbian_p.cpp
index 073ed6b..df1c1ef 100644
--- a/src/corelib/kernel/qcore_symbian_p.cpp
+++ b/src/corelib/kernel/qcore_symbian_p.cpp
@@ -133,7 +133,6 @@ public:
private:
void init()
{
-#ifdef Q_OS_SYMBIAN
_LIT(KLibName_3_1, "qts60plugin_3_1" QT_LIBINFIX_UNICODE L".dll");
_LIT(KLibName_3_2, "qts60plugin_3_2" QT_LIBINFIX_UNICODE L".dll");
_LIT(KLibName_5_0, "qts60plugin_5_0" QT_LIBINFIX_UNICODE L".dll");
@@ -159,7 +158,12 @@ private:
TUidType libUid(KDynamicLibraryUid, KSharedLibraryUid, TUid::Uid(uidValue));
lib.Load(libName, libUid);
-#endif
+
+ // Duplicate lib handle to enable process wide access to it. Since Duplicate overwrites
+ // existing handle without closing it, store original for subsequent closing.
+ RLibrary origHandleCloser = lib;
+ lib.Duplicate(RThread(), EOwnerProcess);
+ origHandleCloser.Close();
}
RLibrary lib;
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index d94cf6d..4abe0ae 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -2122,7 +2122,8 @@ QStringList QCoreApplication::arguments()
l1arg == "-stylesheet" ||
l1arg == "-widgetcount")
;
- else if (l1arg.startsWith("-style="))
+ else if (l1arg.startsWith("-style=") ||
+ l1arg.startsWith("-qmljsdebugger="))
;
else if (l1arg == "-style" ||
l1arg == "-session" ||
diff --git a/src/corelib/kernel/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp
index 5ab867f..02736dd 100644
--- a/src/corelib/kernel/qeventdispatcher_symbian.cpp
+++ b/src/corelib/kernel/qeventdispatcher_symbian.cpp
@@ -232,8 +232,12 @@ void QTimerActiveObject::DoCancel()
void QTimerActiveObject::RunL()
{
- int error;
- QT_TRYCATCH_ERROR(error, Run());
+ int error = KErrNone;
+ if (iStatus == KErrNone) {
+ QT_TRYCATCH_ERROR(error, Run());
+ } else {
+ error = iStatus.Int();
+ }
// All Symbian error codes are negative.
if (error < 0) {
CActiveScheduler::Current()->Error(error); // stop and report here, as this timer will be deleted on scope exit
diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp
index 9dadd82..f50994c 100644
--- a/src/corelib/kernel/qeventdispatcher_unix.cpp
+++ b/src/corelib/kernel/qeventdispatcher_unix.cpp
@@ -549,18 +549,22 @@ int QTimerInfoList::activateTimers()
if (qt_disable_lowpriority_timers || isEmpty())
return 0; // nothing to do
- bool firstTime = true;
- timeval currentTime;
- int n_act = 0, maxCount = count();
+ int n_act = 0, maxCount = 0;
firstTimerInfo = 0;
- while (maxCount--) {
- currentTime = updateCurrentTime();
- if (firstTime) {
- repairTimersIfNeeded();
- firstTime = false;
- }
+ timeval currentTime = updateCurrentTime();
+ repairTimersIfNeeded();
+
+ // Find out how many timer have expired
+ for (QTimerInfoList::const_iterator it = constBegin(); it != constEnd(); ++it) {
+ if (currentTime < (*it)->timeout)
+ break;
+ maxCount++;
+ }
+
+ //fire the timers.
+ while (maxCount--) {
if (isEmpty())
break;
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index e3f537f..153ccdf 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -43,7 +43,7 @@
#include "qcoreapplication.h"
#include "qhash.h"
-#include "qlibrary.h"
+#include <private/qsystemlibrary_p.h>
#include "qpair.h"
#include "qset.h"
#include "qsocketnotifier.h"
@@ -65,7 +65,11 @@ extern uint qGlobalPostedEventsCount();
#endif
#ifndef QS_RAWINPUT
+# ifdef Q_OS_WINCE
+# define QS_RAWINPUT 0x0000
+# else
# define QS_RAWINPUT 0x0400
+# endif
#endif
#ifndef WM_TOUCH
@@ -80,8 +84,7 @@ extern uint qGlobalPostedEventsCount();
enum {
WM_QT_SOCKETNOTIFIER = WM_USER,
- WM_QT_SENDPOSTEDEVENTS = WM_USER + 1,
- SendPostedEventsTimerId = ~1u
+ WM_QT_SENDPOSTEDEVENTS = WM_USER + 1
};
#if defined(Q_OS_WINCE)
@@ -323,11 +326,11 @@ static void resolveTimerAPI()
#endif
triedResolve = true;
#if !defined(Q_OS_WINCE)
- qtimeSetEvent = (ptimeSetEvent)QLibrary::resolve(QLatin1String("winmm"), "timeSetEvent");
- qtimeKillEvent = (ptimeKillEvent)QLibrary::resolve(QLatin1String("winmm"), "timeKillEvent");
+ qtimeSetEvent = (ptimeSetEvent)QSystemLibrary::resolve(QLatin1String("winmm"), "timeSetEvent");
+ qtimeKillEvent = (ptimeKillEvent)QSystemLibrary::resolve(QLatin1String("winmm"), "timeKillEvent");
#else
- qtimeSetEvent = (ptimeSetEvent)QLibrary::resolve(QLatin1String("Mmtimer"), "timeSetEvent");
- qtimeKillEvent = (ptimeKillEvent)QLibrary::resolve(QLatin1String("Mmtimer"), "timeKillEvent");
+ qtimeSetEvent = (ptimeSetEvent)QSystemLibrary::resolve(QLatin1String("Mmtimer"), "timeSetEvent");
+ qtimeKillEvent = (ptimeKillEvent)QSystemLibrary::resolve(QLatin1String("Mmtimer"), "timeKillEvent");
#endif
}
}
@@ -516,12 +519,10 @@ LRESULT QT_WIN_CALLBACK qt_GetMessageHook(int code, WPARAM wp, LPARAM lp)
if (q) {
QEventDispatcherWin32Private *d = q->d_func();
int localSerialNumber = d->serialNumber;
-#ifdef Q_OS_WINCE
- MSG dummyMsg;
- if (HIWORD(GetQueueStatus(QS_INPUT)) == 0
- && PeekMessage(&dummyMsg, 0, WM_TIMER, WM_TIMER, PM_NOREMOVE) == 0
-#else
- if (HIWORD(GetQueueStatus(QS_INPUT | QS_RAWINPUT | QS_TIMER)) == 0
+ MSG unused;
+ if ((HIWORD(GetQueueStatus(QS_INPUT | QS_RAWINPUT)) == 0
+ && PeekMessage(&unused, 0, WM_TIMER, WM_TIMER, PM_NOREMOVE) == 0)
+#ifndef Q_OS_WINCE
|| GetMessageTime() - d->lastMessageTime >= 10
#endif
) {
@@ -824,7 +825,7 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
pHandles[i] = d->winEventNotifierList.at(i)->handle();
emit aboutToBlock();
- waitRet = MsgWaitForMultipleObjectsEx(nCount, pHandles, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE);
+ waitRet = MsgWaitForMultipleObjectsEx(nCount, pHandles, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE | MWMO_INPUTAVAILABLE);
emit awake();
if (waitRet >= WAIT_OBJECT_0 && waitRet < WAIT_OBJECT_0 + nCount) {
d->activateEventNotifier(d->winEventNotifierList.at(waitRet - WAIT_OBJECT_0));
diff --git a/src/corelib/kernel/qmath.qdoc b/src/corelib/kernel/qmath.qdoc
new file mode 100644
index 0000000..48f74b6
--- /dev/null
+++ b/src/corelib/kernel/qmath.qdoc
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in a
+** written agreement between you and Nokia.
+**
+** GNU Free Documentation License
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of this
+** file.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \headerfile <QtCore/qmath.h>
+ \title Math Functions
+ \ingroup funclists
+ \brief The <QtCore/qmath.h> header provides various math functions.
+ \pagekeywords math trigonometry qmath floor ceiling absolute sine cosine tangent inverse tan exponent power natural logarithm
+*/
+
+/*!
+ \fn int qCeil(qreal v)
+ Return the ceiling of the value \a v.
+
+ The ceiling is the smallest integer that is not less than \a v.
+ For example, if \a v is 41.2, then the ceiling is 42.
+
+ \relates <QtCore/qmath.h>
+ \sa qFloor()
+*/
+
+/*!
+ \fn int qFloor(qreal v)
+ Return the floor of the value \a v.
+
+ The floor is the largest integer that is not greater than \a v.
+ For example, if \a v is 41.2, then the floor is 41.
+
+ \relates <QtCore/qmath.h>
+ \sa qCeil()
+*/
+
+/*!
+ \fn qreal qFabs(qreal v)
+ Returns the absolute value of \a v as a qreal.
+*/
+
+/*!
+ \fn qreal qSin(qreal v)
+ Returns the sine of the angle \a v in radians.
+
+ \relates <QtCore/qmath.h>
+ \sa qCos(), qTan()
+*/
+
+/*!
+ \fn qreal qCos(qreal v)
+ Returns the cosine of an angle \a v in radians.
+
+ \relates <QtCore/qmath.h>
+ \sa qSin(), qTan()
+*/
+
+/*!
+ \fn qreal qTan(qreal v)
+ Returns the tangent of an angle \a v in radians.
+
+ \relates <QtCore/qmath.h>
+ \sa qSin(), qCos()
+*/
+
+/*!
+ \fn qreal qAcos(qreal v)
+ Returns the arccosine of \a v as an angle in radians.
+ Arccosine is the inverse operation of cosine.
+
+ \relates <QtCore/qmath.h>
+ \sa qAtan(), qAsin(), qCos()
+*/
+
+/*!
+ \fn qreal qAsin(qreal v)
+ Returns the arcsine of \a v as an angle in radians.
+ Arcsine is the inverse operation of sine.
+
+ \relates <QtCore/qmath.h>
+ \sa qSin(), qAtan(), qAcos()
+*/
+
+/*!
+ \fn qreal qAtan(qreal v)
+ Returns the arctangent of \a v as an angle in radians.
+ Arctangent is the inverse operation of tangent.
+
+ \relates <QtCore/qmath.h>
+ \sa qTan(), qAcos(), qAsin()
+*/
+
+/*!
+ \fn qreal qAtan2(qreal x, qreal y)
+ Returns the arctangent of a point specified by the coordinates \a x and \a y.
+ This function will return the angle and its direction.
+
+ \relates <QtCore/qmath.h>
+ \sa qAtan()
+*/
+
+/*!
+ \fn qreal qSqrt(qreal v)
+ Returns the square root of \a v.
+ This function returns a NaN if \a v is a negative number.
+
+ \relates <QtCore/qmath.h>
+ \sa qPow()
+*/
+
+/*!
+ \fn qreal qLn(qreal v)
+ Returns the natural logarithm of \a v. Natural logarithm uses base e.
+
+ \relates <QtCore/qmath.h>
+ \sa qExp()
+*/
+
+/*!
+ \fn qreal qExp(qreal v)
+ Returns the exponential function of \c e to the power of \a v.
+
+ \relates <QtCore/qmath.h>
+ \sa qLn()
+*/
+
+/*!
+ \fn qreal qPow(qreal x, qreal y)
+ Returns the value of \a x raised to the power of \a y.
+ That is, \a x is the base and \a y is the exponent.
+
+ \relates <QtCore/qmath.h>
+ \sa qSqrt()
+*/
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index a70772f..ceb2a9c 100644
--- a/src/corelib/kernel/qmetaobject.cpp
+++ b/src/corelib/kernel/qmetaobject.cpp
@@ -266,7 +266,25 @@ QObject *QMetaObject::cast(QObject *obj) const
const QMetaObject *m = obj->metaObject();
do {
if (m == this)
- return const_cast<QObject*>(obj);
+ return obj;
+ } while ((m = m->d.superdata));
+ }
+ return 0;
+}
+
+/*!
+ \internal
+
+ Returns \a obj if object \a obj inherits from this
+ meta-object; otherwise returns 0.
+*/
+const QObject *QMetaObject::cast(const QObject *obj) const
+{
+ if (obj) {
+ const QMetaObject *m = obj->metaObject();
+ do {
+ if (m == this)
+ return obj;
} while ((m = m->d.superdata));
}
return 0;
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index 52efcd0..eebb3db 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -156,7 +156,18 @@ void qMetaTypeLoadHelper(QDataStream &stream, T *t)
}
#endif // QT_NO_DATASTREAM
-template <typename T> struct QMetaTypeId2;
+template <typename T>
+struct QMetaTypeId
+{
+ enum { Defined = 0 };
+};
+
+template <typename T>
+struct QMetaTypeId2
+{
+ enum { Defined = QMetaTypeId<T>::Defined };
+ static inline int qt_metatype_id() { return QMetaTypeId<T>::qt_metatype_id(); }
+};
namespace QtPrivate {
template <typename T, bool Defined = QMetaTypeId2<T>::Defined>
@@ -210,19 +221,6 @@ void qRegisterMetaTypeStreamOperators(const char *typeName
#endif // QT_NO_DATASTREAM
template <typename T>
-struct QMetaTypeId
-{
- enum { Defined = 0 };
-};
-
-template <typename T>
-struct QMetaTypeId2
-{
- enum { Defined = QMetaTypeId<T>::Defined };
- static inline int qt_metatype_id() { return QMetaTypeId<T>::qt_metatype_id(); }
-};
-
-template <typename T>
inline int qMetaTypeId(
#ifndef qdoc
T * /* dummy */ = 0
diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h
index b5db936..63fdf76 100644
--- a/src/corelib/kernel/qobject.h
+++ b/src/corelib/kernel/qobject.h
@@ -351,7 +351,7 @@ inline QT_DEPRECATED T qFindChild(const QObject *o, const QString &name = QStrin
{ return o->findChild<T>(name); }
template<typename T>
-inline QList<T> qFindChildren(const QObject *o, const QString &name = QString())
+inline QT_DEPRECATED QList<T> qFindChildren(const QObject *o, const QString &name = QString())
{
return o->findChildren<T>(name);
}
@@ -378,14 +378,10 @@ inline T qobject_cast(QObject *object)
template <class T>
inline T qobject_cast(const QObject *object)
{
- // this will cause a compilation error if T is not const
- register T ptr = static_cast<T>(object);
- Q_UNUSED(ptr);
-
#if !defined(QT_NO_QOBJECT_CHECK)
reinterpret_cast<T>(0)->qt_check_for_QOBJECT_macro(*reinterpret_cast<T>(const_cast<QObject *>(object)));
#endif
- return static_cast<T>(const_cast<QObject *>(reinterpret_cast<T>(0)->staticMetaObject.cast(const_cast<QObject *>(object))));
+ return static_cast<T>(reinterpret_cast<T>(0)->staticMetaObject.cast(object));
}
diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h
index 996fce2..db46ba5 100644
--- a/src/corelib/kernel/qobjectdefs.h
+++ b/src/corelib/kernel/qobjectdefs.h
@@ -298,6 +298,7 @@ struct Q_CORE_EXPORT QMetaObject
const QMetaObject *superClass() const;
QObject *cast(QObject *obj) const;
+ const QObject *cast(const QObject *obj) const;
#ifndef QT_NO_TRANSLATION
// ### Qt 4: Merge overloads
diff --git a/src/corelib/kernel/qpointer.cpp b/src/corelib/kernel/qpointer.cpp
index 5cd0220..fbfb961 100644
--- a/src/corelib/kernel/qpointer.cpp
+++ b/src/corelib/kernel/qpointer.cpp
@@ -41,7 +41,7 @@
/*!
\class QPointer
- \brief The QPointer class is a template class that provides guarded pointers to QObjects.
+ \brief The QPointer class is a template class that provides guarded pointers to QObject.
\ingroup objectmodel
diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h
index a4d45f6..b267954 100644
--- a/src/corelib/kernel/qvariant.h
+++ b/src/corelib/kernel/qvariant.h
@@ -219,6 +219,10 @@ class Q_CORE_EXPORT QVariant
QVariant(Qt::GlobalColor color);
QVariant& operator=(const QVariant &other);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QVariant &operator=(QVariant &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
Type type() const;
int userType() const;
diff --git a/src/corelib/plugin/plugin.pri b/src/corelib/plugin/plugin.pri
index c05ff48..50b005d 100644
--- a/src/corelib/plugin/plugin.pri
+++ b/src/corelib/plugin/plugin.pri
@@ -7,16 +7,21 @@ HEADERS += \
plugin/qlibrary_p.h \
plugin/qplugin.h \
plugin/quuid.h \
- plugin/qfactoryloader_p.h
+ plugin/qfactoryloader_p.h \
+ plugin/qsystemlibrary_p.h \
+ plugin/qelfparser_p.h
SOURCES += \
plugin/qpluginloader.cpp \
plugin/qfactoryloader.cpp \
plugin/quuid.cpp \
- plugin/qlibrary.cpp
+ plugin/qlibrary.cpp \
+ plugin/qelfparser_p.cpp
win32 {
- SOURCES += plugin/qlibrary_win.cpp
+ SOURCES += \
+ plugin/qlibrary_win.cpp \
+ plugin/qsystemlibrary.cpp
}
unix {
diff --git a/src/corelib/plugin/qelfparser_p.cpp b/src/corelib/plugin/qelfparser_p.cpp
new file mode 100644
index 0000000..2e77ae7
--- /dev/null
+++ b/src/corelib/plugin/qelfparser_p.cpp
@@ -0,0 +1,234 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** 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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qlibrary_p.h"
+#include "qelfparser_p.h"
+#include <qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+// #define QELFPARSER_DEBUG 1
+
+const char *QElfParser::parseSectionHeader(const char *data, ElfSectionHeader *sh)
+{
+ sh->name = read<qelfword_t>(data);
+ data += sizeof(qelfword_t); // sh_name
+ sh->type = read<qelfword_t>(data);
+ data += sizeof(qelfword_t) // sh_type
+ + sizeof(qelfaddr_t) // sh_flags
+ + sizeof(qelfaddr_t); // sh_addr
+ sh->offset = read<qelfoff_t>(data);
+ data += sizeof(qelfoff_t); // sh_offset
+ sh->size = read<qelfword_t>(data);
+ data += sizeof(qelfword_t); // sh_size
+ return data;
+}
+
+int QElfParser::parse(const char *dataStart, ulong fdlen, const QString &library, QLibraryPrivate *lib, long *pos, ulong *sectionlen)
+{
+#if defined(QELFPARSER_DEBUG)
+ qDebug() << "QElfParser::parse " << library;
+#endif
+
+ if (fdlen < 64){
+ if (lib)
+ lib->errorString = QLibrary::tr("'%1' is not an ELF object (%2)").arg(library).arg(QLatin1String("file too small"));
+ return NotElf;
+ }
+ const char *data = dataStart;
+ if (qstrncmp(data, "\177ELF", 4) != 0) {
+ if (lib)
+ lib->errorString = QLibrary::tr("'%1' is not an ELF object").arg(library);
+ return NotElf;
+ }
+ // 32 or 64 bit
+ if (data[4] != 1 && data[4] != 2) {
+ if (lib)
+ lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library).arg(QLatin1String("odd cpu architecture"));
+ return Corrupt;
+ }
+ m_bits = (data[4] << 5);
+
+ /* If you remove this check, to read ELF objects of a different arch, please make sure you modify the typedefs
+ to match the _plugin_ architecture.
+ */
+ if ((sizeof(void*) == 4 && m_bits != 32) || (sizeof(void*) == 8 && m_bits != 64)) {
+ if (lib)
+ lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library).arg(QLatin1String("wrong cpu architecture"));
+ return Corrupt;
+ }
+ // endian
+ if (data[5] == 0) {
+ if (lib)
+ lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library).arg(QLatin1String("odd endianess"));
+ return Corrupt;
+ }
+ m_endian = (data[5] == 1 ? ElfLittleEndian : ElfBigEndian);
+
+ data += 16 // e_ident
+ + sizeof(qelfhalf_t) // e_type
+ + sizeof(qelfhalf_t) // e_machine
+ + sizeof(qelfword_t) // e_version
+ + sizeof(qelfaddr_t) // e_entry
+ + sizeof(qelfoff_t); // e_phoff
+
+ qelfoff_t e_shoff = read<qelfoff_t> (data);
+ data += sizeof(qelfoff_t) // e_shoff
+ + sizeof(qelfword_t); // e_flags
+
+ qelfhalf_t e_shsize = read<qelfhalf_t> (data);
+
+ if (e_shsize > fdlen) {
+ if (lib)
+ lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library).arg(QLatin1String("unexpected e_shsize"));
+ return Corrupt;
+ }
+
+ data += sizeof(qelfhalf_t) // e_ehsize
+ + sizeof(qelfhalf_t) // e_phentsize
+ + sizeof(qelfhalf_t); // e_phnum
+
+ qelfhalf_t e_shentsize = read<qelfhalf_t> (data);
+
+ if (e_shentsize % 4){
+ if (lib)
+ lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library).arg(QLatin1String("unexpected e_shentsize"));
+ return Corrupt;
+ }
+ data += sizeof(qelfhalf_t); // e_shentsize
+ qelfhalf_t e_shnum = read<qelfhalf_t> (data);
+ data += sizeof(qelfhalf_t); // e_shnum
+ qelfhalf_t e_shtrndx = read<qelfhalf_t> (data);
+ data += sizeof(qelfhalf_t); // e_shtrndx
+
+ if ((e_shnum * e_shentsize) > fdlen) {
+ if (lib)
+ lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library)
+ .arg(QLatin1String("announced %2 sections, each %3 bytes, exceed file size"))
+ .arg(e_shnum).arg(e_shentsize);
+ return Corrupt;
+ }
+
+#if defined(QELFPARSER_DEBUG)
+ qDebug() << e_shnum << "sections starting at " << ("0x" + QByteArray::number(e_shoff, 16)).data() << "each" << e_shentsize << "bytes";
+#endif
+
+ ElfSectionHeader strtab;
+ qulonglong soff = e_shoff + e_shentsize * (e_shtrndx);
+
+ if ((soff + e_shentsize) > fdlen || soff % 4 || soff == 0) {
+ if (lib)
+ lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library)
+ .arg(QLatin1String("shstrtab section header seems to be at %1"))
+ .arg(QString::number(soff, 16));
+ return Corrupt;
+ }
+
+ parseSectionHeader(dataStart + soff, &strtab);
+ m_stringTableFileOffset = strtab.offset;
+
+ if ((m_stringTableFileOffset + e_shentsize) >= fdlen || m_stringTableFileOffset == 0) {
+ if (lib)
+ lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library)
+ .arg(QLatin1String("string table seems to be at %1"))
+ .arg(QString::number(soff, 16));
+ return Corrupt;
+ }
+
+#if defined(QELFPARSER_DEBUG)
+ qDebug(".shstrtab at 0x%s", QByteArray::number(m_stringTableFileOffset, 16).data());
+#endif
+
+ const char *s = dataStart + e_shoff;
+ for (int i = 0; i < e_shnum; ++i) {
+ ElfSectionHeader sh;
+ parseSectionHeader(s, &sh);
+ if (sh.name == 0) {
+ s += e_shentsize;
+ continue;
+ }
+ const char *shnam = dataStart + m_stringTableFileOffset + sh.name;
+
+ if (m_stringTableFileOffset + sh.name > fdlen) {
+ if (lib)
+ lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library)
+ .arg(QLatin1String("section name %2 of %3 behind end of file"))
+ .arg(i).arg(e_shnum);
+ return Corrupt;
+ }
+
+#if defined(QELFPARSER_DEBUG)
+ qDebug() << "++++" << i << shnam;
+#endif
+
+ if (qstrcmp(shnam, ".qtplugin") == 0 || qstrcmp(shnam, ".rodata") == 0) {
+ if (!(sh.type & 0x1)) {
+ if (shnam[1] == 'r') {
+ if (lib)
+ lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library)
+ .arg(QLatin1String("empty .rodata. not a library."));
+ return Corrupt;
+ }
+#if defined(QELFPARSER_DEBUG)
+ qDebug()<<"section is not program data. skipped.";
+#endif
+ s += e_shentsize;
+ continue;
+ }
+
+ if (sh.offset == 0 || (sh.offset + sh.size) > fdlen) {
+ if (lib)
+ lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library)
+ .arg(QLatin1String("missing section data. This is not a library."));
+ return Corrupt;
+ }
+ *pos = sh.offset;
+ *sectionlen = sh.size - 1;
+ if (shnam[1] == 'q')
+ return Ok;
+ }
+ s += e_shentsize;
+ }
+ return NoQtSection;
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/corelib/plugin/qelfparser_p.h b/src/corelib/plugin/qelfparser_p.h
new file mode 100644
index 0000000..380d5a1
--- /dev/null
+++ b/src/corelib/plugin/qelfparser_p.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** 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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QELFPARSER_P_H
+#define QELFPARSER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <qendian.h>
+#include <qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+class QString;
+class QLibraryPrivate;
+
+typedef quint16 qelfhalf_t;
+typedef quint32 qelfword_t;
+typedef quintptr qelfoff_t;
+typedef quintptr qelfaddr_t;
+
+class QElfParser
+{
+public:
+ enum {Ok = 0, NotElf = 1, NoQtSection = 2, Corrupt = 3};
+ enum {ElfLittleEndian = 0, ElfBigEndian = 1};
+
+ struct ElfSectionHeader
+ {
+ qelfword_t name;
+ qelfword_t type;
+ qelfoff_t offset;
+ qelfword_t size;
+ };
+
+ int m_endian;
+ int m_bits;
+ int m_stringTableFileOffset;
+
+ template <typename T>
+ T read(const char *s)
+ {
+ if (m_endian == ElfBigEndian)
+ return qFromBigEndian<T>(reinterpret_cast<const uchar *>(s));
+ else
+ return qFromLittleEndian<T>(reinterpret_cast<const uchar *>(s));
+ }
+
+ const char *parseSectionHeader(const char* s, ElfSectionHeader *sh);
+ int parse(const char *m_s, ulong fdlen, const QString &library, QLibraryPrivate *lib, long *pos, ulong *sectionlen);
+};
+
+QT_END_NAMESPACE
+
+#endif // QELFPARSER_P_H
+
diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp
index 62d565a..a26dcd8 100644
--- a/src/corelib/plugin/qfactoryloader.cpp
+++ b/src/corelib/plugin/qfactoryloader.cpp
@@ -244,6 +244,14 @@ QObject *QFactoryLoader::instance(const QString &key) const
return 0;
}
+#ifdef Q_WS_X11
+QLibraryPrivate *QFactoryLoader::library(const QString &key) const
+{
+ Q_D(const QFactoryLoader);
+ return d->keyMap.value(d->cs ? key : key.toLower());
+}
+#endif
+
void QFactoryLoader::refreshAll()
{
QMutexLocker locker(qt_factoryloader_mutex());
diff --git a/src/corelib/plugin/qfactoryloader_p.h b/src/corelib/plugin/qfactoryloader_p.h
index 10e6e2a..068c6c7 100644
--- a/src/corelib/plugin/qfactoryloader_p.h
+++ b/src/corelib/plugin/qfactoryloader_p.h
@@ -77,6 +77,10 @@ public:
QStringList keys() const;
QObject *instance(const QString &key) const;
+#ifdef Q_WS_X11
+ QLibraryPrivate *library(const QString &key) const;
+#endif
+
void update();
static void refreshAll();
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp
index f6ae038..f812275 100644
--- a/src/corelib/plugin/qlibrary.cpp
+++ b/src/corelib/plugin/qlibrary.cpp
@@ -38,7 +38,6 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-
#include "qplatformdefs.h"
#include "qlibrary.h"
@@ -61,11 +60,10 @@
#include <qdebug.h>
#include <qvector.h>
#include <qdir.h>
+#include "qelfparser_p.h"
QT_BEGIN_NAMESPACE
-//#define QT_DEBUG_COMPONENT
-
#ifdef QT_NO_DEBUG
# define QLIBRARY_AS_DEBUG false
#else
@@ -295,14 +293,6 @@ static bool qt_parse_pattern(const char *s, uint *version, bool *debug, QByteArr
#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_SYMBIAN) && !defined(QT_NO_PLUGIN_CHECK)
-#if defined(Q_OS_FREEBSD) || defined(Q_OS_LINUX)
-# define USE_MMAP
-QT_BEGIN_INCLUDE_NAMESPACE
-# include <sys/types.h>
-# include <sys/mman.h>
-QT_END_INCLUDE_NAMESPACE
-#endif // Q_OS_FREEBSD || Q_OS_LINUX
-
static long qt_find_pattern(const char *s, ulong s_len,
const char *pattern, ulong p_len)
{
@@ -363,57 +353,51 @@ static bool qt_unix_query(const QString &library, uint *version, bool *debug, QB
}
QByteArray data;
- char *filedata = 0;
- ulong fdlen = 0;
-
-# ifdef USE_MMAP
- char *mapaddr = 0;
- size_t maplen = file.size();
- mapaddr = (char *) mmap(mapaddr, maplen, PROT_READ, MAP_PRIVATE, file.handle(), 0);
- if (mapaddr != MAP_FAILED) {
- // mmap succeeded
- filedata = mapaddr;
- fdlen = maplen;
- } else {
- // mmap failed
- if (qt_debug_component()) {
- qWarning("mmap: %s", qPrintable(qt_error_string(errno)));
- }
- if (lib)
- lib->errorString = QLibrary::tr("Could not mmap '%1': %2")
- .arg(library)
- .arg(qt_error_string());
-# endif // USE_MMAP
+ const char *filedata = 0;
+ ulong fdlen = file.size();
+ filedata = (char *) file.map(0, fdlen);
+ if (filedata == 0) {
// try reading the data into memory instead
data = file.readAll();
- filedata = data.data();
+ filedata = data.constData();
fdlen = data.size();
-# ifdef USE_MMAP
}
-# endif // USE_MMAP
- // verify that the pattern is present in the plugin
+ /*
+ ELF binaries on GNU, have .qplugin sections.
+ */
+ long pos = 0;
const char pattern[] = "pattern=QT_PLUGIN_VERIFICATION_DATA";
const ulong plen = qstrlen(pattern);
- long pos = qt_find_pattern(filedata, fdlen, pattern, plen);
-
+#if defined (Q_OF_ELF) && defined(Q_CC_GNU)
+ int r = QElfParser().parse(filedata, fdlen, library, lib, &pos, &fdlen);
+ if (r == QElfParser::NoQtSection) {
+ if (pos > 0) {
+ // find inside .rodata
+ long rel = qt_find_pattern(filedata + pos, fdlen, pattern, plen);
+ if (rel < 0) {
+ pos = -1;
+ } else {
+ pos += rel;
+ }
+ } else {
+ pos = qt_find_pattern(filedata, fdlen, pattern, plen);
+ }
+ } else if (r != QElfParser::Ok) {
+ if (lib && qt_debug_component()) {
+ qWarning(qPrintable(lib->errorString));
+ }
+ return false;
+ }
+#else
+ pos = qt_find_pattern(filedata, fdlen, pattern, plen);
+#endif // defined(Q_OF_ELF) && defined(Q_CC_GNU)
bool ret = false;
if (pos >= 0)
ret = qt_parse_pattern(filedata + pos, version, debug, key);
if (!ret && lib)
lib->errorString = QLibrary::tr("Plugin verification data mismatch in '%1'").arg(library);
-# ifdef USE_MMAP
- if (mapaddr != MAP_FAILED && munmap(mapaddr, maplen) != 0) {
- if (qt_debug_component())
- qWarning("munmap: %s", qPrintable(qt_error_string(errno)));
- if (lib)
- lib->errorString = QLibrary::tr("Could not unmap '%1': %2")
- .arg(library)
- .arg( qt_error_string() );
- }
-# endif // USE_MMAP
-
file.close();
return ret;
}
@@ -863,10 +847,16 @@ bool QLibraryPrivate::isPlugin(QSettings *settings)
.arg(qt_version&0xff)
.arg(debug ? QLatin1String("debug") : QLatin1String("release"));
} else if (key != QT_BUILD_KEY
+ // we may have some compatibility keys, try them too:
#ifdef QT_BUILD_KEY_COMPAT
- // be sure to load plugins using an older but compatible build key
&& key != QT_BUILD_KEY_COMPAT
#endif
+#ifdef QT_BUILD_KEY_COMPAT2
+ && key != QT_BUILD_KEY_COMPAT2
+#endif
+#ifdef QT_BUILD_KEY_COMPAT3
+ && key != QT_BUILD_KEY_COMPAT3
+#endif
) {
if (qt_debug_component()) {
qWarning("In %s:\n"
@@ -1290,15 +1280,11 @@ QLibrary::LoadHints QLibrary::loadHints() const
/* Internal, for debugging */
bool qt_debug_component()
{
-#if defined(QT_DEBUG_COMPONENT)
- return true; //compatibility?
-#else
static int debug_env = -1;
if (debug_env == -1)
debug_env = QT_PREPEND_NAMESPACE(qgetenv)("QT_DEBUG_PLUGINS").toInt();
return debug_env != 0;
-#endif
}
QT_END_NAMESPACE
diff --git a/src/corelib/plugin/qplugin.h b/src/corelib/plugin/qplugin.h
index 7f541f1..bd49b15 100644
--- a/src/corelib/plugin/qplugin.h
+++ b/src/corelib/plugin/qplugin.h
@@ -101,13 +101,17 @@ void Q_CORE_EXPORT qRegisterStaticPluginInstanceFunction(QtPluginInstanceFunctio
// NOTE: if you change pattern, you MUST change the pattern in
// qlibrary.cpp as well. changing the pattern will break all
// backwards compatibility as well (no old plugins will be loaded).
+// QT5: should probably remove the entire pattern thing and do the section
+// trick for all platforms. for now, keep it and fallback to scan for it.
# ifdef QPLUGIN_DEBUG_STR
# undef QPLUGIN_DEBUG_STR
# endif
# ifdef QT_NO_DEBUG
# define QPLUGIN_DEBUG_STR "false"
+# define QPLUGIN_SECTION_DEBUG_STR ""
# else
# define QPLUGIN_DEBUG_STR "true"
+# define QPLUGIN_SECTION_DEBUG_STR ".debug"
# endif
# define Q_PLUGIN_VERIFICATION_DATA \
static const char qt_plugin_verification_data[] = \
@@ -116,6 +120,13 @@ void Q_CORE_EXPORT qRegisterStaticPluginInstanceFunction(QtPluginInstanceFunctio
"debug="QPLUGIN_DEBUG_STR"\n" \
"buildkey="QT_BUILD_KEY;
+# if defined (Q_OF_ELF) && defined (Q_CC_GNU)
+# define Q_PLUGIN_VERIFICATION_SECTION \
+ __attribute__ ((section (".qtplugin"))) __attribute__((used))
+# else
+# define Q_PLUGIN_VERIFICATION_SECTION
+# endif
+
# if defined (Q_OS_WIN32) && defined(Q_CC_BOR)
# define Q_STANDARD_CALL __stdcall
# else
@@ -123,7 +134,7 @@ void Q_CORE_EXPORT qRegisterStaticPluginInstanceFunction(QtPluginInstanceFunctio
# endif
# define Q_EXPORT_PLUGIN2(PLUGIN, PLUGINCLASS) \
- Q_PLUGIN_VERIFICATION_DATA \
+ Q_PLUGIN_VERIFICATION_SECTION Q_PLUGIN_VERIFICATION_DATA \
Q_EXTERN_C Q_DECL_EXPORT \
const char * Q_STANDARD_CALL qt_plugin_query_verification_data() \
{ return qt_plugin_verification_data; } \
diff --git a/src/corelib/plugin/qsystemlibrary.cpp b/src/corelib/plugin/qsystemlibrary.cpp
new file mode 100644
index 0000000..eeb142b
--- /dev/null
+++ b/src/corelib/plugin/qsystemlibrary.cpp
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** 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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsystemlibrary_p.h"
+#include <QtCore/qvarlengtharray.h>
+#include <QtCore/qstringlist.h>
+#include <QtCore/qfileinfo.h>
+
+/*!
+
+ \internal
+ \class QSystemLibrary
+
+ The purpose of this class is to load only libraries that are located in
+ well-known and trusted locations on the filesystem. It does not suffer from
+ the security problem that QLibrary has, therefore it will never search in
+ the current directory.
+
+ The search order is the same as the order in DLL Safe search mode Windows,
+ except that we don't search:
+ * The current directory
+ * The 16-bit system directory. (normally c:\windows\system)
+ * The Windows directory. (normally c:\windows)
+
+ This means that the effective search order is:
+ 1. Application path.
+ 2. System libraries path.
+ 3. Trying all paths inside the PATH environment variable.
+
+ Note, when onlySystemDirectory is true it will skip 1) and 3).
+
+ DLL Safe search mode is documented in the "Dynamic-Link Library Search
+ Order" document on MSDN.
+
+ Since library loading code is sometimes shared between Windows and WinCE,
+ this class can also be used on WinCE. However, its implementation just
+ calls the LoadLibrary() function. This is ok since it is documented as not
+ loading from the current directory on WinCE. This behaviour is documented
+ in the documentation for LoadLibrary for Windows CE at MSDN.
+ (http://msdn.microsoft.com/en-us/library/ms886736.aspx)
+*/
+#if defined(Q_OS_WINCE)
+HINSTANCE QSystemLibrary::load(const wchar_t *libraryName, bool onlySystemDirectory /* = true */)
+{
+ return ::LoadLibrary(libraryName);
+}
+#else
+
+#if !defined(QT_BOOTSTRAPPED)
+extern QString qAppFileName();
+#endif
+
+static QString qSystemDirectory()
+{
+ QVarLengthArray<wchar_t, MAX_PATH> fullPath;
+
+ UINT retLen = ::GetSystemDirectory(fullPath.data(), MAX_PATH);
+ if (retLen > MAX_PATH) {
+ fullPath.resize(retLen);
+ retLen = ::GetSystemDirectory(fullPath.data(), retLen);
+ }
+ // in some rare cases retLen might be 0
+ return QString::fromWCharArray(fullPath.constData(), int(retLen));
+}
+
+HINSTANCE QSystemLibrary::load(const wchar_t *libraryName, bool onlySystemDirectory /* = true */)
+{
+ QStringList searchOrder;
+
+#if !defined(QT_BOOTSTRAPPED)
+ if (!onlySystemDirectory)
+ searchOrder << QFileInfo(qAppFileName()).path();
+#endif
+ searchOrder << qSystemDirectory();
+
+ if (!onlySystemDirectory) {
+ const QString PATH(QLatin1String(qgetenv("PATH").constData()));
+ searchOrder << PATH.split(QLatin1Char(';'), QString::SkipEmptyParts);
+ }
+ QString fileName = QString::fromWCharArray(libraryName);
+ fileName.append(QLatin1String(".dll"));
+
+ // Start looking in the order specified
+ for (int i = 0; i < searchOrder.count(); ++i) {
+ QString fullPathAttempt = searchOrder.at(i);
+ if (!fullPathAttempt.endsWith(QLatin1Char('\\'))) {
+ fullPathAttempt.append(QLatin1Char('\\'));
+ }
+ fullPathAttempt.append(fileName);
+ HINSTANCE inst = ::LoadLibrary((const wchar_t *)fullPathAttempt.utf16());
+ if (inst != 0)
+ return inst;
+ }
+ return 0;
+
+}
+
+#endif //Q_OS_WINCE
diff --git a/src/corelib/plugin/qsystemlibrary_p.h b/src/corelib/plugin/qsystemlibrary_p.h
new file mode 100644
index 0000000..3251a3c
--- /dev/null
+++ b/src/corelib/plugin/qsystemlibrary_p.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** 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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSYSTEMLIBRARY_P_H
+#define QSYSTEMLIBRARY_P_H
+
+#include <QtCore/qglobal.h>
+#ifdef Q_OS_WIN
+#include <qt_windows.h>
+#include <QtCore/qstring.h>
+
+class QSystemLibrary
+{
+public:
+ explicit QSystemLibrary(const QString &libraryName)
+ {
+ m_libraryName = libraryName;
+ m_handle = 0;
+ m_didLoad = false;
+ }
+
+ explicit QSystemLibrary(const wchar_t *libraryName)
+ {
+ m_libraryName = QString::fromWCharArray(libraryName);
+ m_handle = 0;
+ m_didLoad = false;
+ }
+
+ bool load(bool onlySystemDirectory = true)
+ {
+ m_handle = load((const wchar_t *)m_libraryName.utf16(), onlySystemDirectory);
+ m_didLoad = true;
+ return (m_handle != 0);
+ }
+
+ bool isLoaded()
+ {
+ return (m_handle != 0);
+ }
+
+ void *resolve(const char *symbol)
+ {
+ if (!m_didLoad)
+ load();
+ if (!m_handle)
+ return 0;
+#ifdef Q_OS_WINCE
+ return (void*)GetProcAddress(m_handle, (const wchar_t*)QString::fromLatin1(symbol).utf16());
+#else
+ return (void*)GetProcAddress(m_handle, symbol);
+#endif
+ }
+
+ static void *resolve(const QString &libraryName, const char *symbol)
+ {
+ return QSystemLibrary(libraryName).resolve(symbol);
+ }
+
+ static Q_CORE_EXPORT HINSTANCE load(const wchar_t *lpFileName, bool onlySystemDirectory = true);
+private:
+ HINSTANCE m_handle;
+ QString m_libraryName;
+ bool m_didLoad;
+};
+
+#endif //Q_OS_WIN
+
+#endif //QSYSTEMLIBRARY_P_H
diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp
index a3c702a..d704615 100644
--- a/src/corelib/statemachine/qstatemachine.cpp
+++ b/src/corelib/statemachine/qstatemachine.cpp
@@ -2135,6 +2135,7 @@ void QStateMachine::endMicrostep(QEvent *event)
/*!
\reimp
+ This function will call start() to start the state machine.
*/
void QStateMachine::onEntry(QEvent *event)
{
@@ -2144,6 +2145,8 @@ void QStateMachine::onEntry(QEvent *event)
/*!
\reimp
+ This function will call stop() to stop the state machine and
+ subsequently emit the stopped() signal.
*/
void QStateMachine::onExit(QEvent *event)
{
diff --git a/src/corelib/thread/qatomic.cpp b/src/corelib/thread/qatomic.cpp
index 743da24..697da38 100644
--- a/src/corelib/thread/qatomic.cpp
+++ b/src/corelib/thread/qatomic.cpp
@@ -48,10 +48,9 @@
For atomic operations on pointers, see the QAtomicPointer class.
- An complex operation that completes without interruption is said
- to be \e atomic. The QAtomicInt class provides atomic reference
- counting, test-and-set, fetch-and-store, and fetch-and-add for
- integers.
+ An \e atomic operation is a complex operation that completes without interruption.
+ The QAtomicInt class provides atomic reference counting, test-and-set, fetch-and-store,
+ and fetch-and-add for integers.
\section1 Non-atomic convenience operators
@@ -635,9 +634,8 @@
For atomic operations on integers, see the QAtomicInt class.
- An complex operation that completes without interruption is said
- to be \e atomic. The QAtomicPointer class provides atomic
- test-and-set, fetch-and-store, and fetch-and-add for pointers.
+ An \e atomic operation is a complex operation that completes without interruption.
+ The QAtomicPointer class provides atomic test-and-set, fetch-and-store, and fetch-and-add for pointers.
\section1 Non-atomic convenience operators
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index d193b2e..2824e15 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -142,6 +142,20 @@ static void destroy_current_thread_data_key()
}
Q_DESTRUCTOR_FUNCTION(destroy_current_thread_data_key)
+#ifdef Q_OS_SYMBIAN
+static void init_symbian_thread_handle(RThread &thread)
+{
+ thread = RThread();
+ TThreadId threadId = thread.Id();
+ thread.Open(threadId);
+
+ // Make thread handle accessible process wide
+ RThread originalCloser = thread;
+ thread.Duplicate(thread, EOwnerProcess);
+ originalCloser.Close();
+}
+#endif
+
QThreadData *QThreadData::current()
{
pthread_once(&current_thread_data_once, create_current_thread_data_key);
@@ -182,9 +196,7 @@ void QAdoptedThread::init()
Q_D(QThread);
d->thread_id = pthread_self();
#ifdef Q_OS_SYMBIAN
- d->data->symbian_thread_handle = RThread();
- TThreadId threadId = d->data->symbian_thread_handle.Id();
- d->data->symbian_thread_handle.Open(threadId);
+ init_symbian_thread_handle(d->data->symbian_thread_handle);
#endif
}
@@ -244,9 +256,8 @@ void *QThreadPrivate::start(void *arg)
// RThread and pthread_t, we must delay initialization of the RThread
// handle when creating a thread, until we are running in the new thread.
// Here, we pick up the current thread and assign that to the handle.
- data->symbian_thread_handle = RThread();
- TThreadId threadId = data->symbian_thread_handle.Id();
- data->symbian_thread_handle.Open(threadId);
+ init_symbian_thread_handle(data->symbian_thread_handle);
+
// On symbian, threads other than the main thread are non critical by default
// This means a worker thread can crash without crashing the application - to
// use this feature, we would need to use RThread::Logon in the main thread
@@ -657,6 +668,18 @@ bool QThread::wait(unsigned long time)
return true;
while (d->running) {
+#ifdef Q_OS_SYMBIAN
+ // Check if thread still exists. Needed because kernel will kill it without notification
+ // before global statics are deleted at application exit.
+ if (d->data->symbian_thread_handle.Handle()
+ && d->data->symbian_thread_handle.ExitType() != EExitPending) {
+ // Cannot call finish here as wait is typically called from another thread.
+ // It won't be necessary anyway, as we should never get here under normal operations;
+ // all QThreads are EProcessCritical and therefore cannot normally exit
+ // undetected (i.e. panic) as long as all thread control is via QThread.
+ return true;
+ }
+#endif
if (!d->thread_done.wait(locker.mutex(), time))
return false;
}
diff --git a/src/corelib/tools/qbitarray.h b/src/corelib/tools/qbitarray.h
index 60cdc9c..bd79904 100644
--- a/src/corelib/tools/qbitarray.h
+++ b/src/corelib/tools/qbitarray.h
@@ -63,6 +63,10 @@ public:
explicit QBitArray(int size, bool val = false);
QBitArray(const QBitArray &other) : d(other.d) {}
inline QBitArray &operator=(const QBitArray &other) { d = other.d; return *this; }
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QBitArray &operator=(QBitArray &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
inline int size() const { return (d.size() << 3) - *d.constData(); }
inline int count() const { return (d.size() << 3) - *d.constData(); }
diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp
index 3062c4a..6be3416 100644
--- a/src/corelib/tools/qbytearray.cpp
+++ b/src/corelib/tools/qbytearray.cpp
@@ -46,7 +46,6 @@
#include "qlist.h"
#include "qlocale.h"
#include "qlocale_p.h"
-#include "qunicodetables_p.h"
#include "qscopedpointer.h"
#include <qdatastream.h>
@@ -854,7 +853,7 @@ QByteArray::Data QByteArray::shared_empty = { Q_BASIC_ATOMIC_INITIALIZER(1),
This operation takes \l{constant time}, because QByteArray is
\l{implicitly shared}. This makes returning a QByteArray from a
function very fast. If a shared instance is modified, it will be
- copied (copy-on-write), and that takes \l{linear time}.
+ copied (copy-on-write), taking \l{linear time}.
\sa operator=()
*/
@@ -1190,10 +1189,18 @@ void QByteArray::chop(int n)
Example:
\snippet doc/src/snippets/code/src_corelib_tools_qbytearray.cpp 12
- This operation is typically very fast (\l{constant time}),
- because QByteArray preallocates extra space at the end of the
- character data so it can grow without reallocating the entire
- data each time.
+ Note: QByteArray is an \l{implicitly shared} class. Consequently,
+ if \e this is an empty QByteArray, then \e this will just share
+ the data held in \a ba. In this case, no copying of data is done,
+ taking \l{constant time}. If a shared instance is modified, it will
+ be copied (copy-on-write), taking \l{linear time}.
+
+ If \e this is not an empty QByteArray, a deep copy of the data is
+ performed, taking \l{linear time}.
+
+ This operation typically does not suffer from allocation overhead,
+ because QByteArray preallocates extra space at the end of the data
+ so that it may grow without reallocating for each append operation.
\sa append(), prepend()
*/
@@ -1478,7 +1485,12 @@ QByteArray QByteArray::nulTerminated() const
Note: QByteArray is an \l{implicitly shared} class. Consequently,
if \e this is an empty QByteArray, then \e this will just share
- the data held in \a ba. In this case, no copying of data is done.
+ the data held in \a ba. In this case, no copying of data is done,
+ taking \l{constant time}. If a shared instance is modified, it will
+ be copied (copy-on-write), taking \l{linear time}.
+
+ If \e this is not an empty QByteArray, a deep copy of the data is
+ performed, taking \l{linear time}.
\sa append(), insert()
*/
@@ -1551,14 +1563,18 @@ QByteArray &QByteArray::prepend(char ch)
This is the same as insert(size(), \a ba).
- This operation is typically very fast (\l{constant time}),
- because QByteArray preallocates extra space at the end of the
- character data so it can grow without reallocating the entire
- data each time.
-
Note: QByteArray is an \l{implicitly shared} class. Consequently,
if \e this is an empty QByteArray, then \e this will just share
- the data held in \a ba. In this case, no copying of data is done.
+ the data held in \a ba. In this case, no copying of data is done,
+ taking \l{constant time}. If a shared instance is modified, it will
+ be copied (copy-on-write), taking \l{linear time}.
+
+ If \e this is not an empty QByteArray, a deep copy of the data is
+ performed, taking \l{linear time}.
+
+ This operation typically does not suffer from allocation overhead,
+ because QByteArray preallocates extra space at the end of the data
+ so that it may grow without reallocating for each append operation.
\sa operator+=(), prepend(), insert()
*/
diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h
index a3fe3f5..3cdcaab 100644
--- a/src/corelib/tools/qbytearray.h
+++ b/src/corelib/tools/qbytearray.h
@@ -144,6 +144,10 @@ public:
QByteArray &operator=(const QByteArray &);
QByteArray &operator=(const char *str);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QByteArray &operator=(QByteArray &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
inline int size() const;
bool isEmpty() const;
diff --git a/src/corelib/tools/qchar.cpp b/src/corelib/tools/qchar.cpp
index ed0af4e..bb777cd 100644
--- a/src/corelib/tools/qchar.cpp
+++ b/src/corelib/tools/qchar.cpp
@@ -1630,21 +1630,4 @@ static void canonicalOrderHelper(QString *str, QChar::UnicodeVersion version, in
}
}
-int QT_FASTCALL QUnicodeTables::script(unsigned int uc)
-{
- if (uc > 0xffff)
- return Common;
- int script = uc_scripts[uc >> 7];
- if (script < ScriptSentinel)
- return script;
- script = (((script - ScriptSentinel) * UnicodeBlockSize) + UnicodeBlockCount);
- script = uc_scripts[script + (uc & 0x7f)];
- return script;
-}
-
-Q_CORE_EXPORT QUnicodeTables::LineBreakClass QT_FASTCALL QUnicodeTables::lineBreakClass(uint ucs4)
-{
- return (QUnicodeTables::LineBreakClass) qGetProp(ucs4)->line_break_class;
-}
-
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qcontiguouscache.h b/src/corelib/tools/qcontiguouscache.h
index f767962..4c1a846 100644
--- a/src/corelib/tools/qcontiguouscache.h
+++ b/src/corelib/tools/qcontiguouscache.h
@@ -110,6 +110,10 @@ public:
inline void setSharable(bool sharable) { if (!sharable) detach(); d->sharable = sharable; }
QContiguousCache<T> &operator=(const QContiguousCache<T> &other);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QContiguousCache<T> &operator=(QContiguousCache<T> &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
bool operator==(const QContiguousCache<T> &other) const;
inline bool operator!=(const QContiguousCache<T> &other) const { return !(*this == other); }
diff --git a/src/corelib/tools/qcryptographichash.cpp b/src/corelib/tools/qcryptographichash.cpp
index f418de9..043d6a3 100644
--- a/src/corelib/tools/qcryptographichash.cpp
+++ b/src/corelib/tools/qcryptographichash.cpp
@@ -147,7 +147,7 @@ void QCryptographicHash::addData(const char *data, int length)
}
/*!
- /overload
+ \overload addData()
*/
void QCryptographicHash::addData(const QByteArray &data)
{
diff --git a/src/corelib/tools/qeasingcurve.cpp b/src/corelib/tools/qeasingcurve.cpp
index ee791e0..7fe9170 100644
--- a/src/corelib/tools/qeasingcurve.cpp
+++ b/src/corelib/tools/qeasingcurve.cpp
@@ -332,7 +332,7 @@ public:
enum Type { In, Out, InOut, OutIn };
QEasingCurveFunction(QEasingCurveFunction::Type type = In, qreal period = 0.3, qreal amplitude = 1.0,
- qreal overshoot = 1.70158f)
+ qreal overshoot = 1.70158)
: _t(type), _p(period), _a(amplitude), _o(overshoot)
{ }
virtual ~QEasingCurveFunction() {}
@@ -359,9 +359,9 @@ QEasingCurveFunction *QEasingCurveFunction::copy() const
bool QEasingCurveFunction::operator==(const QEasingCurveFunction& other)
{
return _t == other._t &&
- _p == other._p &&
- _a == other._a &&
- _o == other._o;
+ qFuzzyCompare(_p, other._p) &&
+ qFuzzyCompare(_a, other._a) &&
+ qFuzzyCompare(_o, other._o);
}
QT_BEGIN_INCLUDE_NAMESPACE
@@ -400,8 +400,8 @@ struct ElasticEase : public QEasingCurveFunction
qreal value(qreal t)
{
- qreal p = (_p < 0) ? 0.3f : _p;
- qreal a = (_a < 0) ? 1.0f : _a;
+ qreal p = (_p < 0) ? qreal(0.3) : _p;
+ qreal a = (_a < 0) ? qreal(1.0) : _a;
switch(_t) {
case In:
return easeInElastic(t, a, p);
@@ -420,7 +420,7 @@ struct ElasticEase : public QEasingCurveFunction
struct BounceEase : public QEasingCurveFunction
{
BounceEase(Type type)
- : QEasingCurveFunction(type, 0.3f, 1.0f)
+ : QEasingCurveFunction(type, qreal(0.3), qreal(1.0))
{ }
QEasingCurveFunction *copy() const
@@ -432,7 +432,7 @@ struct BounceEase : public QEasingCurveFunction
qreal value(qreal t)
{
- qreal a = (_a < 0) ? 1.0f : _a;
+ qreal a = (_a < 0) ? qreal(1.0) : _a;
switch(_t) {
case In:
return easeInBounce(t, a);
@@ -451,7 +451,7 @@ struct BounceEase : public QEasingCurveFunction
struct BackEase : public QEasingCurveFunction
{
BackEase(Type type)
- : QEasingCurveFunction(type, 0.3f, 1.0f, 1.70158f)
+ : QEasingCurveFunction(type, qreal(0.3), qreal(1.0), qreal(1.70158))
{ }
QEasingCurveFunction *copy() const
@@ -463,7 +463,7 @@ struct BackEase : public QEasingCurveFunction
qreal value(qreal t)
{
- qreal o = (_o < 0) ? 1.70158f : _o;
+ qreal o = (_o < 0) ? qreal(1.70158) : _o;
switch(_t) {
case In:
return easeInBack(t, o);
@@ -595,7 +595,7 @@ static QEasingCurveFunction *curveToFunctionObject(QEasingCurve::Type type)
curveFunc = new BackEase(BackEase::OutIn);
break;
default:
- curveFunc = new QEasingCurveFunction(QEasingCurveFunction::In, 0.3f, 1.0f, 1.70158f); // ###
+ curveFunc = new QEasingCurveFunction(QEasingCurveFunction::In, qreal(0.3), qreal(1.0), qreal(1.70158));
}
return curveFunc;
@@ -657,9 +657,17 @@ bool QEasingCurve::operator==(const QEasingCurve &other) const
{
bool res = d_ptr->func == other.d_ptr->func
&& d_ptr->type == other.d_ptr->type;
- if (res && d_ptr->config && other.d_ptr->config) {
+ if (res) {
+ if (d_ptr->config && other.d_ptr->config) {
// catch the config content
- res = d_ptr->config->operator==(*(other.d_ptr->config));
+ res = d_ptr->config->operator==(*(other.d_ptr->config));
+
+ } else if (d_ptr->config || other.d_ptr->config) {
+ // one one has a config object, which could contain default values
+ res = qFuzzyCompare(amplitude(), other.amplitude()) &&
+ qFuzzyCompare(period(), other.period()) &&
+ qFuzzyCompare(overshoot(), other.overshoot());
+ }
}
return res;
}
@@ -681,7 +689,7 @@ bool QEasingCurve::operator==(const QEasingCurve &other) const
*/
qreal QEasingCurve::amplitude() const
{
- return d_ptr->config ? d_ptr->config->_a : 1.0;
+ return d_ptr->config ? d_ptr->config->_a : qreal(1.0);
}
/*!
@@ -705,7 +713,7 @@ void QEasingCurve::setAmplitude(qreal amplitude)
*/
qreal QEasingCurve::period() const
{
- return d_ptr->config ? d_ptr->config->_p : 0.3;
+ return d_ptr->config ? d_ptr->config->_p : qreal(0.3);
}
/*!
@@ -729,7 +737,7 @@ void QEasingCurve::setPeriod(qreal period)
*/
qreal QEasingCurve::overshoot() const
{
- return d_ptr->config ? d_ptr->config->_o : 1.70158f;
+ return d_ptr->config ? d_ptr->config->_o : qreal(1.70158) ;
}
/*!
diff --git a/src/corelib/tools/qelapsedtimer_unix.cpp b/src/corelib/tools/qelapsedtimer_unix.cpp
index 2c4ea58..633fa00 100644
--- a/src/corelib/tools/qelapsedtimer_unix.cpp
+++ b/src/corelib/tools/qelapsedtimer_unix.cpp
@@ -40,22 +40,58 @@
****************************************************************************/
#include "qelapsedtimer.h"
-#include "qpair.h"
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
-#if !defined(QT_NO_CLOCK_MONOTONIC)
-# if defined(QT_BOOTSTRAPPED)
-# define QT_NO_CLOCK_MONOTONIC
+#if defined(QT_NO_CLOCK_MONOTONIC) || defined(QT_BOOTSTRAPPED)
+// turn off the monotonic clock
+# ifdef _POSIX_MONOTONIC_CLOCK
+# undef _POSIX_MONOTONIC_CLOCK
# endif
+# define _POSIX_MONOTONIC_CLOCK -1
#endif
QT_BEGIN_NAMESPACE
-static qint64 fractionAdjustment()
+#if (_POSIX_MONOTONIC_CLOCK-0 != 0)
+static const bool monotonicClockChecked = true;
+static const bool monotonicClockAvailable = _POSIX_MONOTONIC_CLOCK > 0;
+#else
+static int monotonicClockChecked = false;
+static int monotonicClockAvailable = false;
+#endif
+
+#ifdef Q_CC_GNU
+# define is_likely(x) __builtin_expect((x), 1)
+#else
+# define is_likely(x) (x)
+#endif
+#define load_acquire(x) ((volatile const int&)(x))
+#define store_release(x,v) ((volatile int&)(x) = (v))
+
+static void unixCheckClockType()
+{
+#if (_POSIX_MONOTONIC_CLOCK-0 == 0)
+ if (is_likely(load_acquire(monotonicClockChecked)))
+ return;
+
+# if defined(_SC_MONOTONIC_CLOCK)
+ // detect if the system support monotonic timers
+ long x = sysconf(_SC_MONOTONIC_CLOCK);
+ store_release(monotonicClockAvailable, x >= 200112L);
+# endif
+
+ store_release(monotonicClockChecked, true);
+#endif
+}
+
+static inline qint64 fractionAdjustment()
{
- if (QElapsedTimer::isMonotonic()) {
+ // disabled, but otherwise indicates bad usage of QElapsedTimer
+ //Q_ASSERT(monotonicClockChecked);
+
+ if (monotonicClockAvailable) {
// the monotonic timer is measured in nanoseconds
// 1 ms = 1000000 ns
return 1000*1000ull;
@@ -68,90 +104,73 @@ static qint64 fractionAdjustment()
bool QElapsedTimer::isMonotonic()
{
-#if (_POSIX_MONOTONIC_CLOCK-0 > 0)
- return true;
-#else
- static int returnValue = 0;
-
- if (returnValue == 0) {
-# if (_POSIX_MONOTONIC_CLOCK-0 < 0) || !defined(_SC_MONOTONIC_CLOCK)
- returnValue = -1;
-# elif (_POSIX_MONOTONIC_CLOCK == 0)
- // detect if the system support monotonic timers
- long x = sysconf(_SC_MONOTONIC_CLOCK);
- returnValue = (x >= 200112L) ? 1 : -1;
-# endif
- }
-
- return returnValue != -1;
-#endif
+ unixCheckClockType();
+ return monotonicClockAvailable;
}
QElapsedTimer::ClockType QElapsedTimer::clockType()
{
- return isMonotonic() ? MonotonicClock : SystemTime;
+ unixCheckClockType();
+ return monotonicClockAvailable ? MonotonicClock : SystemTime;
}
-static inline QPair<long, long> do_gettime()
+static inline void do_gettime(qint64 *sec, qint64 *frac)
{
-#if (_POSIX_MONOTONIC_CLOCK-0 > 0)
- timespec ts;
- clock_gettime(CLOCK_MONOTONIC, &ts);
- return qMakePair<long,long>(ts.tv_sec, ts.tv_nsec);
-#else
-# if !defined(QT_NO_CLOCK_MONOTONIC) && !defined(QT_BOOTSTRAPPED)
- if (QElapsedTimer::isMonotonic()) {
+#if (_POSIX_MONOTONIC_CLOCK-0 >= 0)
+ unixCheckClockType();
+ if (is_likely(monotonicClockAvailable)) {
timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
- return qMakePair<long,long>(ts.tv_sec, ts.tv_nsec);
+ *sec = ts.tv_sec;
+ *frac = ts.tv_nsec;
+ return;
}
-# endif
+#endif
// use gettimeofday
timeval tv;
::gettimeofday(&tv, 0);
- return qMakePair<long,long>(tv.tv_sec, tv.tv_usec);
-#endif
+ *sec = tv.tv_sec;
+ *frac = tv.tv_usec;
}
// used in qcore_unix.cpp and qeventdispatcher_unix.cpp
timeval qt_gettime()
{
- QPair<long, long> r = do_gettime();
+ qint64 sec, frac;
+ do_gettime(&sec, &frac);
timeval tv;
- tv.tv_sec = r.first;
- tv.tv_usec = r.second;
- if (QElapsedTimer::isMonotonic())
+ tv.tv_sec = sec;
+ tv.tv_usec = frac;
+ if (monotonicClockAvailable)
tv.tv_usec /= 1000;
return tv;
}
+static qint64 elapsedAndRestart(qint64 sec, qint64 frac,
+ qint64 *nowsec, qint64 *nowfrac)
+{
+ do_gettime(nowsec, nowfrac);
+ sec = *nowsec - sec;
+ frac = *nowfrac - frac;
+ return sec * Q_INT64_C(1000) + frac / fractionAdjustment();
+}
+
void QElapsedTimer::start()
{
- QPair<long, long> r = do_gettime();
- t1 = r.first;
- t2 = r.second;
+ do_gettime(&t1, &t2);
}
qint64 QElapsedTimer::restart()
{
- QPair<long, long> r = do_gettime();
- qint64 oldt1 = t1;
- qint64 oldt2 = t2;
- t1 = r.first;
- t2 = r.second;
-
- r.first -= oldt1;
- r.second -= oldt2;
- return r.first * Q_INT64_C(1000) + r.second / fractionAdjustment();
+ return elapsedAndRestart(t1, t2, &t1, &t2);
}
qint64 QElapsedTimer::elapsed() const
{
- QElapsedTimer now;
- now.start();
- return msecsTo(now);
+ qint64 sec, frac;
+ return elapsedAndRestart(t1, t2, &sec, &frac);
}
qint64 QElapsedTimer::msecsSinceReference() const
diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h
index 360f99d..992ff33 100644
--- a/src/corelib/tools/qhash.h
+++ b/src/corelib/tools/qhash.h
@@ -283,6 +283,10 @@ public:
inline ~QHash() { if (!d->ref.deref()) freeData(d); }
QHash<Key, T> &operator=(const QHash<Key, T> &other);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QHash<Key, T> &operator=(QHash<Key, T> &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
bool operator==(const QHash<Key, T> &other) const;
inline bool operator!=(const QHash<Key, T> &other) const { return !(*this == other); }
@@ -586,10 +590,11 @@ template <class Key, class T>
Q_INLINE_TEMPLATE QHash<Key, T> &QHash<Key, T>::operator=(const QHash<Key, T> &other)
{
if (d != other.d) {
- other.d->ref.ref();
+ QHashData *o = other.d;
+ o->ref.ref();
if (!d->ref.deref())
freeData(d);
- d = other.d;
+ d = o;
if (!d->sharable)
detach_helper();
}
diff --git a/src/corelib/tools/qlinkedlist.h b/src/corelib/tools/qlinkedlist.h
index d145fe3..c087944 100644
--- a/src/corelib/tools/qlinkedlist.h
+++ b/src/corelib/tools/qlinkedlist.h
@@ -85,6 +85,10 @@ public:
inline QLinkedList(const QLinkedList<T> &l) : d(l.d) { d->ref.ref(); if (!d->sharable) detach(); }
~QLinkedList();
QLinkedList<T> &operator=(const QLinkedList<T> &);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QLinkedList<T> &operator=(QLinkedList<T> &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
bool operator==(const QLinkedList<T> &l) const;
inline bool operator!=(const QLinkedList<T> &l) const { return !(*this == l); }
@@ -312,10 +316,11 @@ template <typename T>
QLinkedList<T> &QLinkedList<T>::operator=(const QLinkedList<T> &l)
{
if (d != l.d) {
- l.d->ref.ref();
+ QLinkedListData *o = l.d;
+ o->ref.ref();
if (!d->ref.deref())
free(d);
- d = l.d;
+ d = o;
if (!d->sharable)
detach_helper();
}
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h
index 99c9795..8f988d6 100644
--- a/src/corelib/tools/qlist.h
+++ b/src/corelib/tools/qlist.h
@@ -50,6 +50,10 @@
#include <iterator>
#include <list>
#endif
+#ifdef Q_COMPILER_INITIALIZER_LISTS
+#include <iterator>
+#include <initializer_list>
+#endif
#include <new>
#include <limits.h>
@@ -118,6 +122,14 @@ public:
inline QList(const QList<T> &l) : d(l.d) { d->ref.ref(); if (!d->sharable) detach_helper(); }
~QList();
QList<T> &operator=(const QList<T> &l);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QList &operator=(QList &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
+#ifdef Q_COMPILER_INITIALIZER_LISTS
+ inline QList(std::initializer_list<T> args) : d(&QListData::shared_null)
+ { d->ref.ref(); qCopy(args.begin(), args.end(), std::back_inserter(*this)); }
+#endif
bool operator==(const QList<T> &l) const;
inline bool operator!=(const QList<T> &l) const { return !(*this == l); }
@@ -424,10 +436,11 @@ template <typename T>
Q_INLINE_TEMPLATE QList<T> &QList<T>::operator=(const QList<T> &l)
{
if (d != l.d) {
- l.d->ref.ref();
+ QListData::Data *o = l.d;
+ o->ref.ref();
if (!d->ref.deref())
free(d);
- d = l.d;
+ d = o;
if (!d->sharable)
detach_helper();
}
diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h
index 2d11613..ce8fd75 100644
--- a/src/corelib/tools/qmap.h
+++ b/src/corelib/tools/qmap.h
@@ -185,6 +185,10 @@ public:
inline ~QMap() { if (!d) return; if (!d->ref.deref()) freeData(d); }
QMap<Key, T> &operator=(const QMap<Key, T> &other);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QMap<Key, T> &operator=(QMap<Key, T> &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
#ifndef QT_NO_STL
explicit QMap(const typename std::map<Key, T> &other);
std::map<Key, T> toStdMap() const;
@@ -424,10 +428,11 @@ template <class Key, class T>
Q_INLINE_TEMPLATE QMap<Key, T> &QMap<Key, T>::operator=(const QMap<Key, T> &other)
{
if (d != other.d) {
- other.d->ref.ref();
+ QMapData* o = other.d;
+ o->ref.ref();
if (!d->ref.deref())
freeData(d);
- d = other.d;
+ d = o;
if (!d->sharable)
detach_helper();
}
diff --git a/src/corelib/tools/qregexp.cpp b/src/corelib/tools/qregexp.cpp
index 36827d0..a0df065 100644
--- a/src/corelib/tools/qregexp.cpp
+++ b/src/corelib/tools/qregexp.cpp
@@ -4172,6 +4172,8 @@ int QRegExp::matchedLength() const
}
#ifndef QT_NO_REGEXP_CAPTURE
+
+#ifndef QT_NO_DEPRECATED
/*!
\obsolete
Returns the number of captures contained in the regular expression.
@@ -4182,6 +4184,7 @@ int QRegExp::numCaptures() const
{
return captureCount();
}
+#endif
/*!
\since 4.6
diff --git a/src/corelib/tools/qregexp.h b/src/corelib/tools/qregexp.h
index e19c130..0b4a702 100644
--- a/src/corelib/tools/qregexp.h
+++ b/src/corelib/tools/qregexp.h
@@ -76,6 +76,10 @@ public:
QRegExp(const QRegExp &rx);
~QRegExp();
QRegExp &operator=(const QRegExp &rx);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QRegExp &operator=(QRegExp &&other)
+ { qSwap(priv,other.priv); return *this; }
+#endif
bool operator==(const QRegExp &rx) const;
inline bool operator!=(const QRegExp &rx) const { return !operator==(rx); }
diff --git a/src/corelib/tools/qset.h b/src/corelib/tools/qset.h
index fe50d4d..dc3c45a 100644
--- a/src/corelib/tools/qset.h
+++ b/src/corelib/tools/qset.h
@@ -61,6 +61,10 @@ public:
inline QSet<T> &operator=(const QSet<T> &other)
{ q_hash = other.q_hash; return *this; }
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QSet<T> &operator=(QSet<T> &&other)
+ { qSwap(q_hash, other.q_hash); return *this; }
+#endif
inline bool operator==(const QSet<T> &other) const
{ return q_hash == other.q_hash; }
diff --git a/src/corelib/tools/qshareddata.h b/src/corelib/tools/qshareddata.h
index 80ba7b7..b646a9d 100644
--- a/src/corelib/tools/qshareddata.h
+++ b/src/corelib/tools/qshareddata.h
@@ -95,9 +95,10 @@ public:
if (o.d != d) {
if (o.d)
o.d->ref.ref();
- if (d && !d->ref.deref())
- delete d;
+ T *old = d;
d = o.d;
+ if (old && !old->ref.deref())
+ delete old;
}
return *this;
}
@@ -105,12 +106,17 @@ public:
if (o != d) {
if (o)
o->ref.ref();
- if (d && !d->ref.deref())
- delete d;
+ T *old = d;
d = o;
+ if (old && !old->ref.deref())
+ delete old;
}
return *this;
}
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QSharedDataPointer<T> &operator=(QSharedDataPointer<T> &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
inline bool operator!() const { return !d; }
@@ -172,9 +178,10 @@ public:
if (o.d != d) {
if (o.d)
o.d->ref.ref();
- if (d && !d->ref.deref())
- delete d;
+ T *old = d;
d = o.d;
+ if (old && !old->ref.deref())
+ delete old;
}
return *this;
}
@@ -182,12 +189,17 @@ public:
if (o != d) {
if (o)
o->ref.ref();
- if (d && !d->ref.deref())
- delete d;
+ T *old = d;
d = o;
+ if (old && !old->ref.deref())
+ delete old;
}
return *this;
}
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QSharedDataPointer<T> &operator=(QSharedDataPointer<T> &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
inline bool operator!() const { return !d; }
diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h
index bb06f3a..20dda12 100644
--- a/src/corelib/tools/qsharedpointer_impl.h
+++ b/src/corelib/tools/qsharedpointer_impl.h
@@ -465,6 +465,13 @@ public:
BaseClass::internalCopy(other);
return *this;
}
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QSharedPointer<T> &operator=(QSharedPointer<T> &&other)
+ {
+ QSharedPointer<T>::internalSwap(other);
+ return *this;
+ }
+#endif
template <class X>
inline QSharedPointer(const QSharedPointer<X> &other) : BaseClass(other)
diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp
index 8005d7d..7babf3a 100644
--- a/src/corelib/tools/qsimd.cpp
+++ b/src/corelib/tools/qsimd.cpp
@@ -41,6 +41,7 @@
#include "qsimd_p.h"
#include <QByteArray>
+#include <stdio.h>
#if defined(Q_OS_WINCE)
#include <windows.h>
@@ -50,15 +51,32 @@
#include <intrin.h>
#endif
+#if defined(Q_OS_LINUX) && defined(__arm__)
+#include "private/qcore_unix_p.h"
+
+// the kernel header definitions for HWCAP_*
+// (the ones we need/may need anyway)
+
+// copied from <asm/hwcap.h> (ARM)
+#define HWCAP_IWMMXT 512
+#define HWCAP_CRUNCH 1024
+#define HWCAP_THUMBEE 2048
+#define HWCAP_NEON 4096
+#define HWCAP_VFPv3 8192
+#define HWCAP_VFPv3D16 16384
+
+// copied from <linux/auxvec.h>
+#define AT_HWCAP 16 /* arch dependent hints at CPU capabilities */
+
+#endif
+
QT_BEGIN_NAMESPACE
-uint qDetectCPUFeatures()
+#if defined (Q_OS_WINCE)
+static inline uint detectProcessorFeatures()
{
- static uint features = 0xffffffff;
- if (features != 0xffffffff)
- return features;
+ uint features = 0;
-#if defined (Q_OS_WINCE)
#if defined (ARM)
if (IsProcessorFeaturePresent(PF_ARM_INTEL_WMMX)) {
features = IWMMXT;
@@ -78,77 +96,98 @@ uint qDetectCPUFeatures()
#endif
features = 0;
return features;
-#elif defined(QT_HAVE_IWMMXT)
+}
+
+#elif defined(__arm__) || defined(__arm) || defined(QT_HAVE_IWMMXT) || defined(QT_HAVE_NEON)
+static inline uint detectProcessorFeatures()
+{
+ uint features = 0;
+
+#if defined(Q_OS_LINUX)
+ int auxv = ::qt_safe_open("/proc/self/auxv", O_RDONLY);
+ if (auxv != -1) {
+ unsigned long vector[64];
+ int nread;
+ while (features == 0) {
+ nread = ::qt_safe_read(auxv, (char *)vector, sizeof vector);
+ if (nread <= 0) {
+ // EOF or error
+ break;
+ }
+
+ int max = nread / (sizeof vector[0]);
+ for (int i = 0; i < max; i += 2)
+ if (vector[i] == AT_HWCAP) {
+ if (vector[i+1] & HWCAP_IWMMXT)
+ features |= IWMMXT;
+ if (vector[i+1] & HWCAP_NEON)
+ features |= NEON;
+ break;
+ }
+ }
+
+ ::qt_safe_close(auxv);
+ return features;
+ }
+ // fall back if /proc/self/auxv wasn't found
+#endif
+
+#if defined(QT_HAVE_IWMMXT)
// runtime detection only available when running as a previlegied process
- static const bool doIWMMXT = !qgetenv("QT_NO_IWMMXT").toInt();
- features = doIWMMXT ? IWMMXT : 0;
- return features;
+ features = IWMMXT;
#elif defined(QT_HAVE_NEON)
- static const bool doNEON = !qgetenv("QT_NO_NEON").toInt();
- features = doNEON ? NEON : 0;
+ features = NEON;
+#endif
+
return features;
-#else
- features = 0;
-#if defined(__x86_64__) || defined(Q_OS_WIN64)
- features = MMX|SSE|SSE2|CMOV;
-#elif defined(__ia64__)
- features = MMX|SSE|SSE2;
+}
+
#elif defined(__i386__) || defined(_M_IX86)
+static inline uint detectProcessorFeatures()
+{
+ uint features = 0;
+
unsigned int extended_result = 0;
unsigned int feature_result = 0;
uint result = 0;
/* see p. 118 of amd64 instruction set manual Vol3 */
#if defined(Q_CC_GNU)
- asm ("push %%ebx\n"
- "pushf\n"
- "pop %%eax\n"
- "mov %%eax, %%ebx\n"
- "xor $0x00200000, %%eax\n"
- "push %%eax\n"
+ long cpuid_supported, tmp1;
+ asm ("pushf\n"
+ "pop %0\n"
+ "mov %0, %1\n"
+ "xor $0x00200000, %0\n"
+ "push %0\n"
"popf\n"
"pushf\n"
- "pop %%eax\n"
- "xor %%edx, %%edx\n"
- "xor %%ebx, %%eax\n"
- "jz 1f\n"
-
- "mov $0x00000001, %%eax\n"
- "cpuid\n"
- "1:\n"
- "pop %%ebx\n"
- "mov %%edx, %0\n"
- "mov %%ecx, %1\n"
- : "=r" (result), "=r" (feature_result)
- :
- : "%eax", "%ecx", "%edx"
- );
+ "pop %0\n"
+ "xor %1, %0\n" // %eax is now 0 if CPUID is not supported
+ : "=a" (cpuid_supported), "=r" (tmp1)
+ );
+ if (cpuid_supported) {
+ asm ("xchg %%ebx, %2\n"
+ "cpuid\n"
+ "xchg %%ebx, %2\n"
+ : "=c" (feature_result), "=d" (result), "=&r" (tmp1)
+ : "a" (1));
- asm ("push %%ebx\n"
- "pushf\n"
- "pop %%eax\n"
- "mov %%eax, %%ebx\n"
- "xor $0x00200000, %%eax\n"
- "push %%eax\n"
- "popf\n"
- "pushf\n"
- "pop %%eax\n"
- "xor %%edx, %%edx\n"
- "xor %%ebx, %%eax\n"
- "jz 2f\n"
+ asm ("xchg %%ebx, %1\n"
+ "cpuid\n"
+ "cmp $0x80000000, %%eax\n"
+ "jnbe 1f\n"
+ "xor %0, %0\n"
+ "jmp 2f\n"
+ "1:\n"
+ "mov $0x80000001, %%eax\n"
+ "cpuid\n"
+ "2:\n"
+ "xchg %%ebx, %1\n"
+ : "=d" (extended_result), "=&r" (tmp1)
+ : "a" (0x80000000)
+ : "%ecx"
+ );
+ }
- "mov $0x80000000, %%eax\n"
- "cpuid\n"
- "cmp $0x80000000, %%eax\n"
- "jbe 2f\n"
- "mov $0x80000001, %%eax\n"
- "cpuid\n"
- "2:\n"
- "pop %%ebx\n"
- "mov %%edx, %0\n"
- : "=r" (extended_result)
- :
- : "%eax", "%ecx", "%edx"
- );
#elif defined (Q_OS_WIN)
_asm {
push eax
@@ -210,6 +249,7 @@ uint qDetectCPUFeatures()
}
#endif
+
// result now contains the standard feature bits
if (result & (1u << 15))
features |= CMOV;
@@ -236,33 +276,23 @@ uint qDetectCPUFeatures()
if (feature_result & (1u << 28))
features |= AVX;
-#endif // i386
+ return features;
+}
-#if defined(__x86_64__) || defined(Q_OS_WIN64)
+#elif defined(__x86_64) || defined(Q_OS_WIN64)
+static inline uint detectProcessorFeatures()
+{
+ uint features = MMX|SSE|SSE2|CMOV;
uint feature_result = 0;
#if defined(Q_CC_GNU)
- asm ("push %%rbx\n"
- "pushf\n"
- "pop %%rax\n"
- "mov %%eax, %%ebx\n"
- "xor $0x00200000, %%eax\n"
- "push %%rax\n"
- "popf\n"
- "pushf\n"
- "pop %%rax\n"
- "xor %%edx, %%edx\n"
- "xor %%ebx, %%eax\n"
- "jz 1f\n"
-
- "mov $0x00000001, %%eax\n"
+ long tmp;
+ asm ("xchg %%rbx, %1\n"
"cpuid\n"
- "1:\n"
- "pop %%rbx\n"
- "mov %%ecx, %0\n"
- : "=r" (feature_result)
- :
- : "%eax", "%ecx", "%edx"
+ "xchg %%rbx, %1\n"
+ : "=c" (feature_result), "=&r" (tmp)
+ : "a" (1)
+ : "%edx"
);
#elif defined (Q_OS_WIN64)
{
@@ -282,33 +312,97 @@ uint qDetectCPUFeatures()
features |= SSE4_2;
if (feature_result & (1u << 28))
features |= AVX;
-#endif // x86_64
-#if defined(QT_HAVE_MMX)
- if (qgetenv("QT_NO_MMX").toInt())
- features ^= MMX;
-#endif
- if (qgetenv("QT_NO_MMXEXT").toInt())
- features ^= MMXEXT;
+ return features;
+}
-#if defined(QT_HAVE_3DNOW)
- if (qgetenv("QT_NO_3DNOW").toInt())
- features ^= MMX3DNOW;
-#endif
- if (qgetenv("QT_NO_3DNOWEXT").toInt())
- features ^= MMX3DNOWEXT;
+#elif defined(__ia64__)
+static inline uint detectProcessorFeatures()
+{
+ return MMX|SSE|SSE2;
+}
-#if defined(QT_HAVE_SSE)
- if (qgetenv("QT_NO_SSE").toInt())
- features ^= SSE;
-#endif
-#if defined(QT_HAVE_SSE2)
- if (qgetenv("QT_NO_SSE2").toInt())
- features ^= SSE2;
+#else
+static inline uint detectProcessorFeatures()
+{
+ return 0;
+}
#endif
+/*
+ * Use kdesdk/scripts/generate_string_table.pl to update the table below.
+ * Here's the data (don't forget the ONE leading space):
+ mmx
+ mmxext
+ mmx3dnow
+ mmx3dnowext
+ sse
+ sse2
+ cmov
+ iwmmxt
+ neon
+ sse3
+ ssse3
+ sse4.1
+ sse4.2
+ avx
+ */
+
+// begin generated
+static const char features_string[] =
+ " mmx\0"
+ " mmxext\0"
+ " mmx3dnow\0"
+ " mmx3dnowext\0"
+ " sse\0"
+ " sse2\0"
+ " cmov\0"
+ " iwmmxt\0"
+ " neon\0"
+ " sse3\0"
+ " ssse3\0"
+ " sse4.1\0"
+ " sse4.2\0"
+ " avx\0"
+ "\0";
+
+static const int features_indices[] = {
+ 0, 5, 13, 23, 36, 41, 47, 53,
+ 61, 67, 73, 80, 88, 96, -1
+};
+// end generated
+
+const int features_count = (sizeof features_indices - 1) / (sizeof features_indices[0]);
+
+uint qDetectCPUFeatures()
+{
+ static QBasicAtomicInt features = Q_BASIC_ATOMIC_INITIALIZER(-1);
+ if (features != -1)
+ return features;
+
+ uint f = detectProcessorFeatures();
+ QByteArray disable = qgetenv("QT_NO_CPU_FEATURE");
+ if (!disable.isEmpty()) {
+ disable.prepend(' ');
+ for (int i = 0; i < features_count; ++i) {
+ if (disable.contains(features_string + features_indices[i]))
+ f &= ~(1 << i);
+ }
+ }
+
+ features = f;
return features;
-#endif
+}
+
+void qDumpCPUFeatures()
+{
+ uint features = qDetectCPUFeatures();
+ printf("Processor features: ");
+ for (int i = 0; i < features_count; ++i) {
+ if (features & (1 << i))
+ printf("%s", features_string + features_indices[i]);
+ }
+ puts("");
}
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h
index a3148fb..664543b 100644
--- a/src/corelib/tools/qsimd_p.h
+++ b/src/corelib/tools/qsimd_p.h
@@ -51,8 +51,13 @@ QT_BEGIN_HEADER
#if defined(QT_NO_MAC_XARCH) || (defined(Q_OS_DARWIN) && (defined(__ppc__) || defined(__ppc64__)))
// Disable MMX and SSE on Mac/PPC builds, or if the compiler
// does not support -Xarch argument passing
-#undef QT_HAVE_SSE2
#undef QT_HAVE_SSE
+#undef QT_HAVE_SSE2
+#undef QT_HAVE_SSE3
+#undef QT_HAVE_SSSE3
+#undef QT_HAVE_SSE4_1
+#undef QT_HAVE_SSE4_2
+#undef QT_HAVE_AVX
#undef QT_HAVE_3DNOW
#undef QT_HAVE_MMX
#endif
@@ -85,6 +90,7 @@ QT_BEGIN_HEADER
// SSE4.1 and SSE4.2 intrinsics
#if (defined(QT_HAVE_SSE4_1) || defined(QT_HAVE_SSE4_2)) && (defined(__SSE4_1__) || defined(Q_CC_MSVC))
#include <smmintrin.h>
+#include <nmmintrin.h>
#endif
// AVX intrinsics
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index 7ea9877..7589f59 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -189,19 +189,6 @@ static int ucstricmp(const ushort *a, const ushort *ae, const uchar *b)
return 1;
}
-// Unicode case-insensitive comparison
-static int ucstrcmp(const QChar *a, int alen, const QChar *b, int blen)
-{
- if (a == b && alen == blen)
- return 0;
- int l = qMin(alen, blen);
- while (l-- && *a == *b)
- a++,b++;
- if (l == -1)
- return (alen-blen);
- return a->unicode() - b->unicode();
-}
-
// Unicode case-sensitive compare two same-sized strings
static int ucstrncmp(const QChar *a, const QChar *b, int l)
{
@@ -212,28 +199,71 @@ static int ucstrncmp(const QChar *a, const QChar *b, int l)
return a->unicode() - b->unicode();
}
+// Unicode case-sensitive comparison
+static int ucstrcmp(const QChar *a, int alen, const QChar *b, int blen)
+{
+ if (a == b && alen == blen)
+ return 0;
+ int l = qMin(alen, blen);
+ int cmp = ucstrncmp(a, b, l);
+ return cmp ? cmp : (alen-blen);
+}
+
// Unicode case-insensitive compare two same-sized strings
static int ucstrnicmp(const ushort *a, const ushort *b, int l)
{
return ucstricmp(a, a + l, b, b + l);
}
+// Benchmarking indicates that doing memcmp is much slower than
+// executing the comparison ourselves.
+//
+// The profiling was done on a population of calls to qMemEquals, generated
+// during a run of the demo browser. The profile of the data (32-bit x86
+// Linux) was:
+//
+// total number of comparisons: 21353
+// longest string compared: 95
+// average comparison length: 14.8786
+// cache-line crosses: 5661 (13.3%)
+// alignment histogram:
+// 0xXXX0 = 512 (1.2%) strings, 0 (0.0%) of which same-aligned
+// 0xXXX2 = 15087 (35.3%) strings, 5145 (34.1%) of which same-aligned
+// 0xXXX4 = 525 (1.2%) strings, 0 (0.0%) of which same-aligned
+// 0xXXX6 = 557 (1.3%) strings, 6 (1.1%) of which same-aligned
+// 0xXXX8 = 509 (1.2%) strings, 0 (0.0%) of which same-aligned
+// 0xXXXa = 24358 (57.0%) strings, 9901 (40.6%) of which same-aligned
+// 0xXXXc = 557 (1.3%) strings, 0 (0.0%) of which same-aligned
+// 0xXXXe = 601 (1.4%) strings, 15 (2.5%) of which same-aligned
+// total = 42706 (100%) strings, 15067 (35.3%) of which same-aligned
+//
+// 92% of the strings have alignment of 2 or 10, which is due to malloc on
+// 32-bit Linux returning values aligned to 8 bytes, and offsetof(array, QString::Data) == 18.
+//
+// The profile on 64-bit will be different since offsetof(array, QString::Data) == 26.
+//
+// The benchmark results were, for a Core-i7 @ 2.67 GHz 32-bit, compiled with -O3 -funroll-loops:
+// 16-bit loads only: 872,301 CPU ticks [Qt 4.5 / memcmp]
+// 32- and 16-bit loads: 773,362 CPU ticks [Qt 4.6]
+// SSE2 "movdqu" 128-bit loads: 618,736 CPU ticks
+// SSE3 "lddqu" 128-bit loads: 619,954 CPU ticks
+// SSSE3 "palignr" corrections: 852,147 CPU ticks
+// SSE4.2 "pcmpestrm": 738,702 CPU ticks
+//
+// The same benchmark on an Atom N450 @ 1.66 GHz, is:
+// 16-bit loads only: 2,185,882 CPU ticks
+// 32- and 16-bit loads: 1,805,060 CPU ticks
+// SSE2 "movdqu" 128-bit loads: 2,529,843 CPU ticks
+// SSE3 "lddqu" 128-bit loads: 2,514,858 CPU ticks
+// SSSE3 "palignr" corrections: 2,160,325 CPU ticks
+// SSE4.2 not available
+//
+// The conclusion we reach is that alignment the SSE2 unaligned code can gain
+// 20% improvement in performance in some systems, but suffers a penalty due
+// to the unaligned loads on others.
+
static bool qMemEquals(const quint16 *a, const quint16 *b, int length)
{
- // Benchmarking indicates that doing memcmp is much slower than
- // executing the comparison ourselves.
- // To make it even faster, we do a 32-bit comparison, comparing
- // twice the amount of data as a normal word-by-word comparison.
- //
- // Benchmarking results on a 2.33 GHz Core2 Duo, with a 64-QChar
- // block of data, with 4194304 iterations (per iteration):
- // operation usec cpu ticks
- // memcmp 330 710
- // 16-bit 79 167-171
- // 32-bit aligned 49 105-109
- //
- // Testing also indicates that unaligned 32-bit loads are as
- // performant as 32-bit aligned.
if (a == b || !length)
return true;
@@ -927,6 +957,24 @@ QString QString::fromWCharArray(const wchar_t *string, int size)
\sa utf16(), toAscii(), toLatin1(), toUtf8(), toLocal8Bit()
*/
+template<typename T> int toUcs4_helper(const unsigned short *uc, int length, T *out)
+{
+ int i = 0;
+ for (; i < length; ++i) {
+ uint u = uc[i];
+ if (QChar::isHighSurrogate(u) && i < length-1) {
+ ushort low = uc[i+1];
+ if (QChar::isLowSurrogate(low)) {
+ ++i;
+ u = QChar::surrogateToUcs4(u, low);
+ }
+ }
+ *out = T(u);
+ ++out;
+ }
+ return i;
+}
+
/*!
\since 4.2
@@ -951,21 +999,7 @@ int QString::toWCharArray(wchar_t *array) const
memcpy(array, utf16(), sizeof(wchar_t)*length());
return length();
} else {
- wchar_t *a = array;
- const unsigned short *uc = utf16();
- for (int i = 0; i < length(); ++i) {
- uint u = uc[i];
- if (QChar::isHighSurrogate(u) && i + 1 < length()) {
- ushort low = uc[i+1];
- if (QChar::isLowSurrogate(low)) {
- u = QChar::surrogateToUcs4(u, low);
- ++i;
- }
- }
- *a = wchar_t(u);
- ++a;
- }
- return a - array;
+ return toUcs4_helper<wchar_t>(utf16(), length(), array);
}
}
@@ -3701,7 +3735,7 @@ QByteArray QString::toUtf8() const
Returns a UCS-4/UTF-32 representation of the string as a QVector<uint>.
UCS-4 is a Unicode codec and is lossless. All characters from this string
- can be encoded in UCS-4.
+ can be encoded in UCS-4. The vector is not null terminated.
\sa fromUtf8(), toAscii(), toLatin1(), toLocal8Bit(), QTextCodec, fromUcs4(), toWCharArray()
*/
@@ -3709,20 +3743,8 @@ QVector<uint> QString::toUcs4() const
{
QVector<uint> v(length());
uint *a = v.data();
- const unsigned short *uc = utf16();
- for (int i = 0; i < length(); ++i) {
- uint u = uc[i];
- if (QChar(u).isHighSurrogate() && i < length()-1) {
- ushort low = uc[i+1];
- if (QChar(low).isLowSurrogate()) {
- ++i;
- u = QChar::surrogateToUcs4(u, low);
- }
- }
- *a = u;
- ++a;
- }
- v.resize(a - v.data());
+ int len = toUcs4_helper<uint>(utf16(), length(), a);
+ v.resize(len);
return v;
}
@@ -3943,8 +3965,8 @@ QString QString::fromUtf8(const char *str, int size)
This function checks for a Byte Order Mark (BOM). If it is missing,
host byte order is assumed.
- This function is comparatively slow.
- Use QString(const ushort *, int) or QString(const ushort *) if possible.
+ This function is slow compared to the other Unicode conversions.
+ Use QString(const QChar *, int) or QString(const QChar *) if possible.
QString makes a deep copy of the Unicode data.
@@ -8961,4 +8983,114 @@ static inline bool qt_ends_with(const QChar *haystack, int haystackLen,
return true;
}
+/*!
+ \since 4.8
+
+ Returns a Latin-1 representation of the string as a QByteArray.
+
+ The returned byte array is undefined if the string contains non-Latin1
+ characters. Those characters may be suppressed or replaced with a
+ question mark.
+
+ \sa toAscii(), toUtf8(), toLocal8Bit(), QTextCodec
+*/
+QByteArray QStringRef::toLatin1() const
+{
+ return toLatin1_helper(unicode(), length());
+}
+
+/*!
+ \since 4.8
+
+ Returns an 8-bit representation of the string as a QByteArray.
+
+ If a codec has been set using QTextCodec::setCodecForCStrings(),
+ it is used to convert Unicode to 8-bit char; otherwise this
+ function does the same as toLatin1().
+
+ Note that, despite the name, this function does not necessarily return an US-ASCII
+ (ANSI X3.4-1986) string and its result may not be US-ASCII compatible.
+
+ \sa toLatin1(), toUtf8(), toLocal8Bit(), QTextCodec
+*/
+QByteArray QStringRef::toAscii() const
+{
+#ifndef QT_NO_TEXTCODEC
+ if (QString::codecForCStrings)
+ return QString::codecForCStrings->fromUnicode(unicode(), length());
+#endif // QT_NO_TEXTCODEC
+ return toLatin1();
+}
+
+/*!
+ \since 4.8
+
+ Returns the local 8-bit representation of the string as a
+ QByteArray. The returned byte array is undefined if the string
+ contains characters not supported by the local 8-bit encoding.
+
+ QTextCodec::codecForLocale() is used to perform the conversion from
+ Unicode. If the locale encoding could not be determined, this function
+ does the same as toLatin1().
+
+ If this string contains any characters that cannot be encoded in the
+ locale, the returned byte array is undefined. Those characters may be
+ suppressed or replaced by another.
+
+ \sa toAscii(), toLatin1(), toUtf8(), QTextCodec
+*/
+QByteArray QStringRef::toLocal8Bit() const
+{
+#ifndef QT_NO_TEXTCODEC
+ if (QTextCodec::codecForLocale())
+ return QTextCodec::codecForLocale()->fromUnicode(unicode(), length());
+#endif // QT_NO_TEXTCODEC
+ return toLatin1();
+}
+
+/*!
+ \since 4.8
+
+ Returns a UTF-8 representation of the string as a QByteArray.
+
+ UTF-8 is a Unicode codec and can represent all characters in a Unicode
+ string like QString.
+
+ However, in the Unicode range, there are certain codepoints that are not
+ considered characters. The Unicode standard reserves the last two
+ codepoints in each Unicode Plane (U+FFFE, U+FFFF, U+1FFFE, U+1FFFF,
+ U+2FFFE, etc.), as well as 16 codepoints in the range U+FDD0..U+FDDF,
+ inclusive, as non-characters. If any of those appear in the string, they
+ may be discarded and will not appear in the UTF-8 representation, or they
+ may be replaced by one or more replacement characters.
+
+ \sa toAscii(), toLatin1(), toLocal8Bit(), QTextCodec
+*/
+QByteArray QStringRef::toUtf8() const
+{
+ if (isNull())
+ return QByteArray();
+
+ return QUtf8::convertFromUnicode(constData(), length(), 0);
+}
+
+/*!
+ \since 4.8
+
+ Returns a UCS-4/UTF-32 representation of the string as a QVector<uint>.
+
+ UCS-4 is a Unicode codec and is lossless. All characters from this string
+ can be encoded in UCS-4.
+
+ \sa fromUtf8(), toAscii(), toLatin1(), toLocal8Bit(), QTextCodec, fromUcs4(), toWCharArray()
+*/
+QVector<uint> QStringRef::toUcs4() const
+{
+ QVector<uint> v(length());
+ uint *a = v.data();
+ int len = toUcs4_helper<uint>(reinterpret_cast<const unsigned short *>(unicode()), length(), a);
+ v.resize(len);
+ return v;
+}
+
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index 7f7e475..589fdc2 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -104,7 +104,10 @@ public:
QString &operator=(QChar c);
QString &operator=(const QString &);
inline QString &operator=(const QLatin1String &);
-
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QString &operator=(QString &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
inline int size() const { return d->size; }
inline int count() const { return d->size; }
inline int length() const;
@@ -613,6 +616,7 @@ private:
ushort asciiCache : 1;
ushort capacity : 1;
ushort reserved : 11;
+ // ### Qt5: try to ensure that "array" is aligned to 16 bytes on both 32- and 64-bit
ushort array[1];
};
static Data shared_null;
@@ -1161,6 +1165,12 @@ public:
inline const QChar *data() const { return unicode(); }
inline const QChar *constData() const { return unicode(); }
+ QByteArray toAscii() const Q_REQUIRED_RESULT;
+ QByteArray toLatin1() const Q_REQUIRED_RESULT;
+ QByteArray toUtf8() const Q_REQUIRED_RESULT;
+ QByteArray toLocal8Bit() const Q_REQUIRED_RESULT;
+ QVector<uint> toUcs4() const Q_REQUIRED_RESULT;
+
inline void clear() { m_string = 0; m_position = m_size = 0; }
QString toString() const;
inline bool isEmpty() const { return m_size == 0; }
diff --git a/src/corelib/tools/qstringmatcher.cpp b/src/corelib/tools/qstringmatcher.cpp
index 80a8457..d445ed4 100644
--- a/src/corelib/tools/qstringmatcher.cpp
+++ b/src/corelib/tools/qstringmatcher.cpp
@@ -40,7 +40,6 @@
****************************************************************************/
#include "qstringmatcher.h"
-#include "qunicodetables_p.h"
QT_BEGIN_NAMESPACE
diff --git a/src/corelib/tools/qunicodetables.cpp b/src/corelib/tools/qunicodetables.cpp
index 9df31e5..68e72cc 100644
--- a/src/corelib/tools/qunicodetables.cpp
+++ b/src/corelib/tools/qunicodetables.cpp
@@ -4345,6 +4345,11 @@ Q_CORE_EXPORT const QUnicodeTables::Properties * QT_FASTCALL QUnicodeTables::pro
return uc_properties + index;
}
+Q_CORE_EXPORT QUnicodeTables::LineBreakClass QT_FASTCALL QUnicodeTables::lineBreakClass(uint ucs4)
+{
+ return (QUnicodeTables::LineBreakClass)qGetProp(ucs4)->line_break_class;
+}
+
static const ushort specialCaseMap[] = {
0x53, 0x73, 0x0,
0x53, 0x53, 0x0,
@@ -8561,7 +8566,7 @@ static const unsigned char uc_scripts[] = {
Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited,
Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited,
Common, Common, Common, Common, Greek, Greek, Common, Common,
- Common, Common, Greek, Greek, Greek, Greek, Common, Common,
+ Common, Common, Greek, Greek, Greek, Greek, Common, Common,
/* U+0380-03ff at offset 640 */
Common, Common, Common, Common, Greek, Greek, Greek, Common,
@@ -8579,7 +8584,7 @@ static const unsigned char uc_scripts[] = {
Greek, Greek, Coptic, Coptic, Coptic, Coptic, Coptic, Coptic,
Coptic, Coptic, Coptic, Coptic, Coptic, Coptic, Coptic, Coptic,
Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
- Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
+ Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
/* U+0480-04ff at offset 768 */
Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Common,
@@ -8597,7 +8602,7 @@ static const unsigned char uc_scripts[] = {
Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic,
Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic,
Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic,
- Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic,
+ Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic,
/* U+0500-057f at offset 896 */
Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic,
@@ -8615,7 +8620,7 @@ static const unsigned char uc_scripts[] = {
Common, Armenian, Armenian, Armenian, Armenian, Armenian, Armenian, Armenian,
Armenian, Armenian, Armenian, Armenian, Armenian, Armenian, Armenian, Armenian,
Armenian, Armenian, Armenian, Armenian, Armenian, Armenian, Armenian, Armenian,
- Armenian, Armenian, Armenian, Armenian, Armenian, Armenian, Armenian, Armenian,
+ Armenian, Armenian, Armenian, Armenian, Armenian, Armenian, Armenian, Armenian,
/* U+0580-05ff at offset 1024 */
Armenian, Armenian, Armenian, Armenian, Armenian, Armenian, Armenian, Armenian,
@@ -8633,7 +8638,7 @@ static const unsigned char uc_scripts[] = {
Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew,
Hebrew, Hebrew, Hebrew, Common, Common, Common, Common, Common,
Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Common, Common, Common,
- Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
/* U+0600-067f at offset 1152 */
Common, Common, Common, Common, Common, Common, Common, Common,
@@ -8651,7 +8656,7 @@ static const unsigned char uc_scripts[] = {
Common, Common, Common, Common, Common, Common, Common, Common,
Common, Common, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
Inherited, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
- Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
/* U+0680-06ff at offset 1280 */
Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
@@ -8669,7 +8674,7 @@ static const unsigned char uc_scripts[] = {
Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
- Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
/* U+0700-077f at offset 1408 */
Syriac, Syriac, Syriac, Syriac, Syriac, Syriac, Syriac, Syriac,
@@ -8687,7 +8692,7 @@ static const unsigned char uc_scripts[] = {
Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Common, Common,
Common, Common, Common, Common, Common, Common, Common, Common,
- Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
/* U+0780-07ff at offset 1536 */
Thaana, Thaana, Thaana, Thaana, Thaana, Thaana, Thaana, Thaana,
@@ -8705,7 +8710,7 @@ static const unsigned char uc_scripts[] = {
Nko, Nko, Nko, Nko, Nko, Nko, Nko, Nko,
Nko, Nko, Nko, Nko, Nko, Nko, Nko, Nko,
Nko, Nko, Nko, Nko, Nko, Nko, Nko, Nko,
- Nko, Nko, Nko, Common, Common, Common, Common, Common,
+ Nko, Nko, Nko, Common, Common, Common, Common, Common,
/* U+0900-097f at offset 1664 */
Common, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari,
@@ -8723,7 +8728,7 @@ static const unsigned char uc_scripts[] = {
Devanagari, Devanagari, Devanagari, Devanagari, Common, Common, Devanagari, Devanagari,
Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari,
Common, Common, Common, Common, Common, Common, Common, Common,
- Common, Common, Common, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari,
+ Common, Common, Common, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari,
/* U+0980-09ff at offset 1792 */
Common, Bengali, Bengali, Bengali, Common, Bengali, Bengali, Bengali,
@@ -8741,7 +8746,7 @@ static const unsigned char uc_scripts[] = {
Bengali, Bengali, Bengali, Bengali, Common, Common, Bengali, Bengali,
Bengali, Bengali, Bengali, Bengali, Bengali, Bengali, Bengali, Bengali,
Bengali, Bengali, Bengali, Bengali, Bengali, Bengali, Bengali, Bengali,
- Bengali, Bengali, Bengali, Common, Common, Common, Common, Common,
+ Bengali, Bengali, Bengali, Common, Common, Common, Common, Common,
/* U+0a00-0a7f at offset 1920 */
Common, Gurmukhi, Gurmukhi, Gurmukhi, Common, Gurmukhi, Gurmukhi, Gurmukhi,
@@ -8759,7 +8764,7 @@ static const unsigned char uc_scripts[] = {
Common, Common, Common, Common, Common, Common, Gurmukhi, Gurmukhi,
Gurmukhi, Gurmukhi, Gurmukhi, Gurmukhi, Gurmukhi, Gurmukhi, Gurmukhi, Gurmukhi,
Gurmukhi, Gurmukhi, Gurmukhi, Gurmukhi, Gurmukhi, Common, Common, Common,
- Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
/* U+0a80-0aff at offset 2048 */
Common, Gujarati, Gujarati, Gujarati, Common, Gujarati, Gujarati, Gujarati,
@@ -8777,7 +8782,7 @@ static const unsigned char uc_scripts[] = {
Gujarati, Gujarati, Gujarati, Gujarati, Common, Common, Gujarati, Gujarati,
Gujarati, Gujarati, Gujarati, Gujarati, Gujarati, Gujarati, Gujarati, Gujarati,
Common, Gujarati, Common, Common, Common, Common, Common, Common,
- Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
/* U+0b00-0b7f at offset 2176 */
Common, Oriya, Oriya, Oriya, Common, Oriya, Oriya, Oriya,
@@ -8795,7 +8800,7 @@ static const unsigned char uc_scripts[] = {
Oriya, Oriya, Common, Common, Common, Common, Oriya, Oriya,
Oriya, Oriya, Oriya, Oriya, Oriya, Oriya, Oriya, Oriya,
Oriya, Oriya, Common, Common, Common, Common, Common, Common,
- Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
/* U+0b80-0bff at offset 2304 */
Common, Common, Tamil, Tamil, Common, Tamil, Tamil, Tamil,
@@ -8813,7 +8818,7 @@ static const unsigned char uc_scripts[] = {
Common, Common, Common, Common, Common, Common, Tamil, Tamil,
Tamil, Tamil, Tamil, Tamil, Tamil, Tamil, Tamil, Tamil,
Tamil, Tamil, Tamil, Tamil, Tamil, Tamil, Tamil, Tamil,
- Tamil, Tamil, Tamil, Common, Common, Common, Common, Common,
+ Tamil, Tamil, Tamil, Common, Common, Common, Common, Common,
/* U+0c00-0c7f at offset 2432 */
Common, Telugu, Telugu, Telugu, Common, Telugu, Telugu, Telugu,
@@ -8831,7 +8836,7 @@ static const unsigned char uc_scripts[] = {
Telugu, Telugu, Common, Common, Common, Common, Telugu, Telugu,
Telugu, Telugu, Telugu, Telugu, Telugu, Telugu, Telugu, Telugu,
Common, Common, Common, Common, Common, Common, Common, Common,
- Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
/* U+0c80-0cff at offset 2560 */
Common, Common, Kannada, Kannada, Common, Kannada, Kannada, Kannada,
@@ -8849,7 +8854,7 @@ static const unsigned char uc_scripts[] = {
Kannada, Kannada, Kannada, Kannada, Common, Common, Kannada, Kannada,
Kannada, Kannada, Kannada, Kannada, Kannada, Kannada, Kannada, Kannada,
Common, Kannada, Kannada, Common, Common, Common, Common, Common,
- Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
/* U+0d00-0d7f at offset 2688 */
Common, Common, Malayalam, Malayalam, Common, Malayalam, Malayalam, Malayalam,
@@ -8867,7 +8872,7 @@ static const unsigned char uc_scripts[] = {
Malayalam, Malayalam, Common, Common, Common, Common, Malayalam, Malayalam,
Malayalam, Malayalam, Malayalam, Malayalam, Malayalam, Malayalam, Malayalam, Malayalam,
Common, Common, Common, Common, Common, Common, Common, Common,
- Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
/* U+0d80-0dff at offset 2816 */
Common, Common, Sinhala, Sinhala, Common, Sinhala, Sinhala, Sinhala,
@@ -8885,7 +8890,7 @@ static const unsigned char uc_scripts[] = {
Common, Common, Common, Common, Common, Common, Common, Common,
Common, Common, Common, Common, Common, Common, Common, Common,
Common, Common, Sinhala, Sinhala, Sinhala, Common, Common, Common,
- Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
/* U+0e00-0e7f at offset 2944 */
Common, Thai, Thai, Thai, Thai, Thai, Thai, Thai,
@@ -8903,7 +8908,7 @@ static const unsigned char uc_scripts[] = {
Common, Common, Common, Common, Common, Common, Common, Common,
Common, Common, Common, Common, Common, Common, Common, Common,
Common, Common, Common, Common, Common, Common, Common, Common,
- Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
/* U+0e80-0eff at offset 3072 */
Common, Lao, Lao, Common, Lao, Common, Common, Lao,
@@ -8921,7 +8926,7 @@ static const unsigned char uc_scripts[] = {
Common, Common, Common, Common, Common, Common, Common, Common,
Common, Common, Common, Common, Common, Common, Common, Common,
Common, Common, Common, Common, Common, Common, Common, Common,
- Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
/* U+0f00-0f7f at offset 3200 */
Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan,
@@ -8939,7 +8944,7 @@ static const unsigned char uc_scripts[] = {
Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan,
Tibetan, Tibetan, Tibetan, Common, Common, Common, Common, Common,
Common, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan,
- Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan,
+ Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan,
/* U+0f80-0fff at offset 3328 */
Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan,
@@ -8957,7 +8962,7 @@ static const unsigned char uc_scripts[] = {
Common, Common, Common, Common, Common, Common, Common, Common,
Common, Common, Common, Common, Common, Common, Common, Common,
Common, Common, Common, Common, Common, Common, Common, Common,
- Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
/* U+1000-107f at offset 3456 */
Myanmar, Myanmar, Myanmar, Myanmar, Myanmar, Myanmar, Myanmar, Myanmar,
@@ -8975,7 +8980,7 @@ static const unsigned char uc_scripts[] = {
Common, Common, Common, Common, Common, Common, Common, Common,
Common, Common, Common, Common, Common, Common, Common, Common,
Common, Common, Common, Common, Common, Common, Common, Common,
- Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
/* U+1080-10ff at offset 3584 */
Common, Common, Common, Common, Common, Common, Common, Common,
@@ -8993,7 +8998,7 @@ static const unsigned char uc_scripts[] = {
Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Georgian,
Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Georgian,
Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Georgian,
- Georgian, Georgian, Georgian, Common, Georgian, Common, Common, Common,
+ Georgian, Georgian, Georgian, Common, Georgian, Common, Common, Common,
/* U+1100-117f at offset 3712 */
Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
@@ -9011,7 +9016,7 @@ static const unsigned char uc_scripts[] = {
Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
- Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
/* U+1180-11ff at offset 3840 */
Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
@@ -9029,7 +9034,7 @@ static const unsigned char uc_scripts[] = {
Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
- Hangul, Hangul, Common, Common, Common, Common, Common, Common,
+ Hangul, Hangul, Common, Common, Common, Common, Common, Common,
/* U+1680-16ff at offset 3968 */
Ogham, Ogham, Ogham, Ogham, Ogham, Ogham, Ogham, Ogham,
@@ -9047,7 +9052,7 @@ static const unsigned char uc_scripts[] = {
Runic, Runic, Runic, Runic, Runic, Runic, Runic, Runic,
Runic, Runic, Runic, Common, Common, Common, Runic, Runic,
Runic, Common, Common, Common, Common, Common, Common, Common,
- Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
/* U+1780-17ff at offset 4096 */
Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer,
@@ -9065,7 +9070,7 @@ static const unsigned char uc_scripts[] = {
Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer,
Khmer, Khmer, Common, Common, Common, Common, Common, Common,
Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer,
- Khmer, Khmer, Common, Common, Common, Common, Common, Common,
+ Khmer, Khmer, Common, Common, Common, Common, Common, Common,
/* U+1980-19ff at offset 4224 */
NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue,
@@ -9083,7 +9088,7 @@ static const unsigned char uc_scripts[] = {
Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer,
Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer,
Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer,
- Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer,
+ Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer,
/* U+1d00-1d7f at offset 4352 */
Latin, Latin, Latin, Latin, Latin, Latin, Latin, Latin,
@@ -9101,7 +9106,7 @@ static const unsigned char uc_scripts[] = {
Greek, Greek, Latin, Latin, Latin, Latin, Greek, Greek,
Greek, Greek, Greek, Latin, Latin, Latin, Latin, Latin,
Latin, Latin, Latin, Latin, Latin, Latin, Latin, Latin,
- Cyrillic, Latin, Latin, Latin, Latin, Latin, Latin, Latin,
+ Cyrillic, Latin, Latin, Latin, Latin, Latin, Latin, Latin,
/* U+1d80-1dff at offset 4480 */
Latin, Latin, Latin, Latin, Latin, Latin, Latin, Latin,
@@ -9119,7 +9124,7 @@ static const unsigned char uc_scripts[] = {
Common, Common, Common, Common, Common, Common, Common, Common,
Common, Common, Common, Common, Common, Common, Common, Common,
Common, Common, Common, Common, Common, Common, Common, Common,
- Common, Common, Common, Common, Common, Common, Inherited, Inherited,
+ Common, Common, Common, Common, Common, Common, Inherited, Inherited,
/* U+1f00-1f7f at offset 4608 */
Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
@@ -9137,7 +9142,7 @@ static const unsigned char uc_scripts[] = {
Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
- Greek, Greek, Greek, Greek, Greek, Greek, Common, Common,
+ Greek, Greek, Greek, Greek, Greek, Greek, Common, Common,
/* U+1f80-1fff at offset 4736 */
Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
@@ -9155,7 +9160,7 @@ static const unsigned char uc_scripts[] = {
Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
Common, Common, Greek, Greek, Greek, Common, Greek, Greek,
- Greek, Greek, Greek, Greek, Greek, Greek, Greek, Common,
+ Greek, Greek, Greek, Greek, Greek, Greek, Greek, Common,
/* U+2000-207f at offset 4864 */
Common, Common, Common, Common, Common, Common, Common, Common,
@@ -9173,7 +9178,7 @@ static const unsigned char uc_scripts[] = {
Common, Common, Common, Common, Common, Common, Common, Common,
Common, Common, Common, Common, Common, Common, Common, Common,
Common, Latin, Common, Common, Common, Common, Common, Common,
- Common, Common, Common, Common, Common, Common, Common, Latin,
+ Common, Common, Common, Common, Common, Common, Common, Latin,
/* U+2080-20ff at offset 4992 */
Common, Common, Common, Common, Common, Common, Common, Common,
@@ -9191,7 +9196,7 @@ static const unsigned char uc_scripts[] = {
Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited,
Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited,
Common, Common, Common, Common, Common, Common, Common, Common,
- Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
/* U+2100-217f at offset 5120 */
Common, Common, Common, Common, Common, Common, Common, Common,
@@ -9209,7 +9214,7 @@ static const unsigned char uc_scripts[] = {
Common, Common, Common, Common, Common, Common, Common, Common,
Common, Common, Common, Common, Common, Common, Common, Common,
Common, Common, Common, Common, Common, Common, Common, Common,
- Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
/* U+2d00-2d7f at offset 5248 */
Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Georgian,
@@ -9227,7 +9232,7 @@ static const unsigned char uc_scripts[] = {
Tifinagh, Tifinagh, Tifinagh, Tifinagh, Tifinagh, Tifinagh, Common, Common,
Common, Common, Common, Common, Common, Common, Common, Tifinagh,
Common, Common, Common, Common, Common, Common, Common, Common,
- Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
/* U+3000-307f at offset 5376 */
Common, Common, Common, Common, Common, Han, Common, Han,
@@ -9245,7 +9250,7 @@ static const unsigned char uc_scripts[] = {
Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana,
Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana,
Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana,
- Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana,
+ Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana,
/* U+3080-30ff at offset 5504 */
Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana,
@@ -9263,7 +9268,7 @@ static const unsigned char uc_scripts[] = {
Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana,
Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana,
Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana,
- Katakana, Katakana, Katakana, Common, Common, Katakana, Katakana, Katakana,
+ Katakana, Katakana, Katakana, Common, Common, Katakana, Katakana, Katakana,
/* U+3100-317f at offset 5632 */
Common, Common, Common, Common, Common, Bopomofo, Bopomofo, Bopomofo,
@@ -9281,7 +9286,7 @@ static const unsigned char uc_scripts[] = {
Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
- Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
/* U+3180-31ff at offset 5760 */
Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
@@ -9299,7 +9304,7 @@ static const unsigned char uc_scripts[] = {
Common, Common, Common, Common, Common, Common, Common, Common,
Common, Common, Common, Common, Common, Common, Common, Common,
Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana,
- Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana,
+ Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana,
/* U+3200-327f at offset 5888 */
Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
@@ -9317,7 +9322,7 @@ static const unsigned char uc_scripts[] = {
Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
- Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Common, Common,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Common, Common,
/* U+d780-d7ff at offset 6016 */
Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
@@ -9335,7 +9340,7 @@ static const unsigned char uc_scripts[] = {
Common, Common, Common, Common, Common, Common, Common, Common,
Common, Common, Common, Common, Common, Common, Common, Common,
Common, Common, Common, Common, Common, Common, Common, Common,
- Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
/* U+fb00-fb7f at offset 6144 */
Latin, Latin, Latin, Latin, Latin, Latin, Latin, Common,
@@ -9353,7 +9358,7 @@ static const unsigned char uc_scripts[] = {
Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
- Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
/* U+fb80-fbff at offset 6272 */
Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
@@ -9371,7 +9376,7 @@ static const unsigned char uc_scripts[] = {
Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
- Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
/* U+fd00-fd7f at offset 6400 */
Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
@@ -9389,7 +9394,7 @@ static const unsigned char uc_scripts[] = {
Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
- Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
/* U+fd80-fdff at offset 6528 */
Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
@@ -9407,7 +9412,7 @@ static const unsigned char uc_scripts[] = {
Common, Common, Common, Common, Common, Common, Common, Common,
Common, Common, Common, Common, Common, Common, Common, Common,
Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
- Arabic, Arabic, Arabic, Arabic, Arabic, Common, Common, Common,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Common, Common, Common,
/* U+fe00-fe7f at offset 6656 */
Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited,
@@ -9425,7 +9430,7 @@ static const unsigned char uc_scripts[] = {
Common, Common, Common, Common, Common, Common, Common, Common,
Common, Common, Common, Common, Common, Common, Common, Common,
Arabic, Arabic, Arabic, Arabic, Arabic, Common, Arabic, Arabic,
- Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
/* U+fe80-feff at offset 6784 */
Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
@@ -9443,7 +9448,7 @@ static const unsigned char uc_scripts[] = {
Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
- Arabic, Arabic, Arabic, Arabic, Arabic, Common, Common, Common,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Common, Common, Common,
/* U+ff80-ffff at offset 6912 */
Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana,
@@ -9461,9 +9466,21 @@ static const unsigned char uc_scripts[] = {
Common, Common, Common, Common, Common, Common, Common, Common,
Common, Common, Common, Common, Common, Common, Common, Common,
Common, Common, Common, Common, Common, Common, Common, Common,
- Common, Common, Common, Common, Common, Common, Common, Common
+ Common, Common, Common, Common, Common, Common, Common, Common
};
} // namespace QUnicodeTables
+Q_CORE_EXPORT int QT_FASTCALL QUnicodeTables::script(uint ucs4)
+{
+ if (ucs4 > 0xffff)
+ return Common;
+ int script = uc_scripts[ucs4 >> 7];
+ if (script < ScriptSentinel)
+ return script;
+ script = (((script - ScriptSentinel) * UnicodeBlockSize) + UnicodeBlockCount);
+ script = uc_scripts[script + (ucs4 & 0x7f)];
+ return script;
+}
+
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qunicodetables_p.h b/src/corelib/tools/qunicodetables_p.h
index 5c7cc08..be52bf9 100644
--- a/src/corelib/tools/qunicodetables_p.h
+++ b/src/corelib/tools/qunicodetables_p.h
@@ -162,20 +162,6 @@ namespace QUnicodeTables {
enum { ScriptSentinel = 32 };
- // see http://www.unicode.org/reports/tr14/tr14-19.html
- // we don't use the XX, AI and CB properties and map them to AL instead.
- // as we don't support any EBDIC based OS'es, NL is ignored and mapped to AL as well.
- enum LineBreakClass {
- LineBreak_OP, LineBreak_CL, LineBreak_QU, LineBreak_GL, LineBreak_NS,
- LineBreak_EX, LineBreak_SY, LineBreak_IS, LineBreak_PR, LineBreak_PO,
- LineBreak_NU, LineBreak_AL, LineBreak_ID, LineBreak_IN, LineBreak_HY,
- LineBreak_BA, LineBreak_BB, LineBreak_B2, LineBreak_ZW, LineBreak_CM,
- LineBreak_WJ, LineBreak_H2, LineBreak_H3, LineBreak_JL, LineBreak_JV,
- LineBreak_JT, LineBreak_SA, LineBreak_SG,
- LineBreak_SP, LineBreak_CR, LineBreak_LF, LineBreak_BK
- };
-
-
enum GraphemeBreak {
GraphemeBreakOther,
GraphemeBreakCR,
@@ -217,6 +203,20 @@ namespace QUnicodeTables {
};
+ // see http://www.unicode.org/reports/tr14/tr14-19.html
+ // we don't use the XX, AI and CB properties and map them to AL instead.
+ // as we don't support any EBDIC based OS'es, NL is ignored and mapped to AL as well.
+ enum LineBreakClass {
+ LineBreak_OP, LineBreak_CL, LineBreak_QU, LineBreak_GL, LineBreak_NS,
+ LineBreak_EX, LineBreak_SY, LineBreak_IS, LineBreak_PR, LineBreak_PO,
+ LineBreak_NU, LineBreak_AL, LineBreak_ID, LineBreak_IN, LineBreak_HY,
+ LineBreak_BA, LineBreak_BB, LineBreak_B2, LineBreak_ZW, LineBreak_CM,
+ LineBreak_WJ, LineBreak_H2, LineBreak_H3, LineBreak_JL, LineBreak_JV,
+ LineBreak_JT, LineBreak_SA, LineBreak_SG,
+ LineBreak_SP, LineBreak_CR, LineBreak_LF, LineBreak_BK
+ };
+
+
Q_CORE_EXPORT QUnicodeTables::LineBreakClass QT_FASTCALL lineBreakClass(uint ucs4);
inline int lineBreakClass(const QChar &ch)
{ return lineBreakClass(ch.unicode()); }
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
index 5613c12..c16aefb 100644
--- a/src/corelib/tools/qvector.h
+++ b/src/corelib/tools/qvector.h
@@ -53,6 +53,9 @@
#endif
#include <stdlib.h>
#include <string.h>
+#ifdef Q_COMPILER_INITIALIZER_LISTS
+#include <initializer_list>
+#endif
QT_BEGIN_HEADER
@@ -118,6 +121,13 @@ public:
inline QVector(const QVector<T> &v) : d(v.d) { d->ref.ref(); if (!d->sharable) detach_helper(); }
inline ~QVector() { if (!d) return; if (!d->ref.deref()) free(p); }
QVector<T> &operator=(const QVector<T> &v);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QVector<T> operator=(QVector<T> &&other)
+ { qSwap(p, other.p); return *this; }
+#endif
+#ifdef Q_COMPILER_INITIALIZER_LISTS
+ inline QVector(std::initializer_list<T> args);
+#endif
bool operator==(const QVector<T> &v) const;
inline bool operator!=(const QVector<T> &v) const { return !(*this == v); }
@@ -293,11 +303,10 @@ public:
#ifndef QT_NO_STL
static inline QVector<T> fromStdVector(const std::vector<T> &vector)
- { QVector<T> tmp; qCopy(vector.begin(), vector.end(), std::back_inserter(tmp)); return tmp; }
+ { QVector<T> tmp; tmp.reserve(vector.size()); qCopy(vector.begin(), vector.end(), std::back_inserter(tmp)); return tmp; }
inline std::vector<T> toStdVector() const
- { std::vector<T> tmp; qCopy(constBegin(), constEnd(), std::back_inserter(tmp)); return tmp; }
+ { std::vector<T> tmp; tmp.reserve(size()); qCopy(constBegin(), constEnd(), std::back_inserter(tmp)); return tmp; }
#endif
-
private:
friend class QRegion; // Optimization for QRegion::rects()
@@ -377,10 +386,11 @@ inline void QVector<T>::replace(int i, const T &t)
template <typename T>
QVector<T> &QVector<T>::operator=(const QVector<T> &v)
{
- v.d->ref.ref();
+ QVectorData *o = v.d;
+ o->ref.ref();
if (!d->ref.deref())
free(p);
- d = v.d;
+ d = o;
if (!d->sharable)
detach_helper();
return *this;
@@ -425,6 +435,22 @@ QVector<T>::QVector(int asize, const T &t)
new (--i) T(t);
}
+#ifdef Q_COMPILER_INITIALIZER_LISTS
+template <typename T>
+QVector<T>::QVector(std::initializer_list<T> args)
+{
+ d = malloc(args.size());
+ d->ref = 1;
+ d->alloc = d->size = args.size();
+ d->sharable = true;
+ d->capacity = false;
+ T* i = p->array + d->size;
+ auto it = args.end();
+ while (i != p->array)
+ new (--i) T(*(--it));
+}
+#endif
+
template <typename T>
void QVector<T>::free(Data *x)
{